A Versioning Strategy

Retired Content

The Web Service Software Factory is now maintained by the community and can be found on the Service Factory site.

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies.
This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Retired: November 2011

Specific tasks must be performed during service development to reduce the complexity of evolving the service. These tasks and design decisions are defined in the following sections and will be augmented with scenarios in a future version of this topic.

XML Namespaces

XML namespaces qualify XML elements and attributes within a document to prevent them from being interpreted as different nodes with the same local name. Distinct namespaces can be applied to various parts of a Web service, but in most cases only two kinds of namespaces need to be defined: one for the service interface and one for the reusable types defined in the messages.

The namespace defined for the service can be used across all parts of the service (for example, bindings, messages, or interfaces) because these parts usually are not deployed and versioned independently of each other.

Messages are made up of primitive types (for example, strings and integers) and/or custom types. Custom types can be used for only a single operation or they may have been defined as part of an enterprise schema or industry specification to be reused across operations or services. Because reusable types are used with other services, they should have a namespace different from the service interface.

An identifier that represents the major version of the interface and reusable types should be reflected in the namespace. The month and year of the release date is commonly used for this identifier (for example, http://globalbank.com/PaymentServices/PaymentTransferService/2006/12).

Message Design

Messages refer to the payload of data and metadata transferred between a service and consumer. A message can be a request or response and contains primitive and complex types. For more information about messages, see Message Design.

Messages are a common element of services that evolve over time. How they are designed influences how easily they evolve and how useful they are in other contexts. The goal of message design, as it relates to versioning, is to be as explicit as possible for the service description without losing the ability to apply minor revisions in the future.

These goals can be achieved by making all the properties optional for the messages and the complex types the messages contain. To appreciate this design, it is helpful to compare it to other message designs that are used:

  • Strings and XML. Some messages are defined as a single string and this string may or may not contain XML data. Other messages have one type that is an XML node or element. Both of these designs share common advantages and disadvantages. They are very easy to evolve because there are no expectations on the messages, but because they do not set any expectations, they are useless from a code generation perspective. As a result of this, if a developer-friendly API is desired for the consumer or service, much more work is required.
  • Strong typing. Some messages explicitly define each property and specify whether that value is required. This design results in a robust API for the service and its consumers, but it reduces the flexibility in how the messages evolve.

There are other advantages to this message design. Members of messages and custom types are optional by default in ASMX and WCF. The serialization engine used by ASMX and WCF services also handles optional members correctly.

Message Validation

Message validation is a common requirement for many services. The WSDL document or related XML schemas being used to define messages should not be used to accomplish this validation for reasons defined earlier in Principles and Motivations. Instead, validation should use external documents. These documents may be XML schemas, regular expression statements, or some other document. The validation rules and the means to apply them should be defined in the service's documentation.

Decoupling the validation requirements from the service description also allow each of these items to independently evolve. Changes to the validation requirements may result in a breaking or non-breaking change. The same is true about a change to the service description.

Applying Changes

The following tasks should be completed when evolving a service:

Minor revisions:

  • Do not change the XML namespace of the message, type, or service being changed.
  • Do not change the endpoint address of the service.
  • New consumers of this service may be deployed, but the existing consumers will continue to operate as they did before the change.
  • Publish new documentation, metadata, and notifications about the change in accordance with the change control process that has been communicated.

Major revisions:

  • Change the XML namespace so it reflects the new release date.
  • Deploy the new service to a test environment so consumers can be tested.
  • Change the endpoint address of the service.
  • Test and deploy the new consumers of the service.
  • Deprecate the old service in a manner and on a timeline in accordance with the change control policy that has been communicated.

Consumer Constraints

Frequently, constraints are placed on a service by some of its consumers. These constraints reduce the flexibility the service has to evolve. In this scenario, the service may choose to evolve differently for different consumers. For this to happen, the consumer must send some form of information that distinguishes the consumer in the message. The service interface then uses this information to dispatch the message to the appropriate implementation.

Another option to increase flexibility involves associating a consumer with the specific operations that consumer will use. This association can take place during the subscription of a service and can be updated at any time. These associations will allow the service to know exactly what consumers will be affected by specific changes to the service.