Designing and versioning compatible Web services


In any Web service implementation, whether it's part of a large scale SOA or a simpler point-to-point implementation, when service providers evolve and add new functionality, service consumers need to adapt. Such changes are typically expensive and time-consuming to implement and coordinate. In this article, we'll propose a set of guidelines that we've found useful for versioning and discuss some approaches for effectively evolving Web Services.

First we'll discuss some basic Web service concepts relevant for versioning and service evolution, define compatibility, and describe compatible evolution in a Web services world. Then we'll present a set of guidelines for versioning and some approaches for implementing backward-compatible Web services. A sample Web service application illustrating these concepts is included in the Downloadable resources section of this article. We also briefly describe WebSphere Web Services Registry and Repository and some of the governance features it offers.

Web services concepts

Two Web service concepts are useful when thinking about compatible Web service evolution--the message-centric nature of Web services and the transparency of implementation.

Web services are fundamentally message-centric. All the information required to complete a transaction should ideally be carried in SOAP messages. Any details that aren't present in SOAP messages should not be relevant for request or response processing. This simplifies things by allowing us to focus our evolution strategy on the messages.

Implementation transparency, which implies that the service interface hides all implementation details, means we can create an evolution strategy at the interface level, without getting into implementation details.

Business requirements and backward compatibility

For the purposes of this article, our fundamental assumption is that a new service will be compatible with older service requesters only in cases where new business features introduced by the new service can be safely ignored by the older requesters. In cases where this is not true, the change to the service is considered an incompatible change.

Let's look at a top-down, request-response Web service implementation scenario in which the following are true:

  • The service is defined by its interface using WSDL, which may refer to one or more XML schema documents.
  • The service follows the "wrapped document-literal" style.
  • You can attach a version number to both the request and the response schema of an operation, as well as to the the service WSDL. We'll describe how to do this later in the article.
  • Only the latest version of the service is deployed.
  • There may be multiple versions of service requesters. A service requester version is assumed to be at the same version as the WSDL version it was generated from.
  • XML schema validation can be done by the provider when it receives a request and by the requester when it receives a response. Schema validation is used only as a means for validating changes to the schema. It's not necessary to keep it on at run-time.

Backward compatibility

What exactly do we mean by backward-compatibility? A change to a service is backward-compatible if either of the following conditions is true:

  1. A new operation is added without changes to existing message definitions. Because the service uses the wrapped document-literal style, new request and response messages are created for the new operation, and existing message definitions are not changed. Requesters that are unaware of this new operation are oblivious to such a change and therefore, remain compatible with the new version.
  2. Messages exchanged by an existing operation are modified such that:
    • The change to the request schema is a backward-compatible change in the sense that request messages from older requesters can be validated against the current schema of the request message defined in the latest service WSDL, as shown in Figure 1. For example, the v1.0 requester in Figure 1 was built from an older WSDL that referred to an older XSD, so the request message it produces conforms to an older XSD. The WSDL of the newer v1.2 service refers to a newer XSD. For backward-compatibility of the request message, older v1.0 request message should be able to be validated against the newer v1.2 XSD referred to in the latest service WSDL.
      Figure 1. Request message evolution
      Figure 1. Request message evolution
      Figure 1. Request message evolution
    • The change to the response schema is a forward-compatible change. The latest response message from the service provider can be validated against the response schema that the older requesters are using, as shown in Figure 2. For example, the v1.0 requester was built from an older WSDL that referred to an older XSD, so it expects response messages to conform to the older v1.0 XSD. The WSDL of the newer v1.2 service refers to a v1.2 XSD. For forward-compatibility of the response message, it should be possible to validate the v1.2 response message from the service against the v1.0 XSD referred to in the v1.0 service requester.
      Figure 2. Response message evolution
      Figure 2. Response message evolution
      Figure 2. Response message evolution

For our purposes, any other types of changes that affect the payload of the SOAP message imply an incompatible change to the service.

To get a better sense of this, let's consider a frequently encountered scenario in which the first version of a service gets deployed and has multiple service requesters. Over time, the service evolves, and a newer version is deployed. Along with it, some, but not all, service requesters are upgraded. We expect the service to be able to consume messages from both older and newer requesters. Such a change to the service is backward-compatible as the service is compatible with older requesters.

Note: In this article, we won't discuss forward-compatible changes to a service in which newer requesters invoke older services. Such situations should be avoided in practical Web service deployments. However, designing backward-compatible services requires forward-compatibility for the response message as noted above.


In this article, we'll focus on message-based incompatibility and exclude other factors from our definition of incompatibility. For example, a JMS-based Web service provider cannot be directly consumed by an HTTP-based requester even if the messages they exchange are compatible, but for the purposes of this article, we won't consider them incompatible. An Enterprise Service Bus (ESB), which does protocol mediation, can allow them to interoperate without code changes on either side. Quality of Service, Policy or Security related service changes, although important from a versioning and evolution perspective, are also excluded from our discussion, as we focus only on functional changes to services. Any strategy for managing such changes should be compatible with the message- centric strategy presented here.

Version numbering and compatibility

It's common to attach a unique version identifier to a component. We'll assume that you have a means for attaching a version number to a WSDL. For example, you can use a tModel associated with a service in UDDI, which is supposed to store concrete information about the service, to store the version number along with the reference to the WSDL for the service. See "Introduce a version number to qualify the interface tModel" in Best practices for Web services versioning for details on this approach. WebSphere Web Services Registry and Repository provides a direct way to hold version number information for a WSDL and XSDs. You can also attach a version number simply by annotating the WSDL.

We'll also mark the changes to the XML schema with a version number in the schema itself to indicate when changes were introduced. This makes it easy to identify the capabilities of a deployed version, helps a requester know if it can expect compatibility, and helps with documentation and support. You can use any label, such as a date, to identify the version, but we'll use the conventional MAJOR.MINOR versioning scheme common in software products, as follows:

  • For an incompatible service change, we'll assume that the change is major and change the major version number as a result. Old version: N.m => New version: (N+1).0
  • For backward-compatible service changes, we'll assume the change is minor and change only the minor version number as a result. Old version: N.m => New version: N.(m+1)

The requester version number will be the same as the version of the WSDL it was generated from. The following will hold true from a compatibility perspective:

  • A service requester with major version N should be able to interoperate with all service providers with the same major version N.
  • A version N.m indicates that it has a semantic understanding of the entire response message, up to minor version m from the service provider at the same major version N. For example, a v2.3 requester should understand the response messages from the following service versions: v2.0, v2.1, v2.2 and v2.3. It will still be able to consume a v2.4 message, but will ignore the new data that is sent as part of minor revision 4.

Guidelines for compatible evolution

Now that you have an understanding of compatibility, let's look at some guidelines that will help you make compatible changes to your Web services.

Plan Early

You should begin planning for compatible evolution and versioning when designing the service, and support for versioning should be part of version 1.0. As you'll see later, planning early makes it much easier to handle versioning. However, even if you didn't plan for evolution in v1.0, you can introduce it in v2.0 by following the approach described in this article.

Business needs first

Whether a service can evolve onto a compatible minor version should be analyzed first from a business requirements perspective, and only then from a technical angle.

A simple discount example illustrates this. Let's say a service requester gets a price quote for books. Now the service is enhanced and, when there is a discount, it also informs the service consumer about the discount amount. Based on this, if you make a backward-compatible change to the service, and introduce discount as an optional element (in the response schema) with a minor version release of the service, older requesters will ignore this field, since they were not designed to interpret it, and will remain functional. Clearly, this doesn't satisfy the business requirements, since the discount amount needs to be interpreted if present. Therefore, even though it is technically possible to have a backward-compatible change to the service, in this case it should be treated as an incompatible change.

Avoid semantic changes if possible

Try not to change the meaning of existing constituents of a message.

For example, if the original version of a service assumes GMT time zone for all timestamps it sends as part of a message, it should not evolve to a newer version and change the time zone to EDT. Such changes are hard to track and their impact may go unnoticed until the service is in production and end users start noticing issues. Instead, make explicit additions when necessary. For example, in this case, you should add a new time-zone attribute.

Address evolution at an interface level

This allows you to address the problem of compatible evolution at a Web service level, that is, at the level of the WSDL and XML schema, and to understand the wider impact of changes. Only after addressing the problem at the interface should you move on to versioning the components of the service implementation. Internal implementation versioning is typically easier to manage because you have better control over your internal environment than you have over external service consumers.

Use wrapped document-literal Web services

Document-oriented Web services enable you to fully exploit the message-based aspect of Web services and leverage the XML schema for the versioning approach described later in this article. As you'll see, it's possible to achieve compatibility at a message level if the business requirements permit backward-compatibility. The wrapped document-literal style helps when a new operation is added because a new request element is defined for the operation, which reduces the possibility of inadvertently modifying existing XML elements to cater to new operations. We also recommend defining a new element for the response message with a naming convention such as operationName_Response.

Avoid namespace changes for compatible changes

Try to avoid namespace changes for backward-compatible changes because these changes typically translate into code changes for the consumer implementation. If the change is incompatible and the consumers have to upgrade anyway, namespace changes are justified.

Don't remove or modify existing operations in a WSDL

As we mentioned when we defined compatibility, the only WSDL change that is compatible is adding new operations (and associated schema changes, bindings, and so on) in a wrapped document-literal WSDL. Do not delete or rename operations, or change existing message definitions.

Adopt a version numbering scheme

When the versioning strategy is clear, you can use a UDDI registry or a product such as WebSphere Service Registry and Repository to implement and enforce the version management strategy.

A recommended versioning strategy for Web services

In our example, the service is defined by a WSDL and version numbers are associated with the WSDL.

  1. Use the major version number as part of the namespace name. For example, for a major version 1, you can use http://service.WS.v1 as the WSDL namespace and http://types.WS.v1 for the XML schema. You can use any namespace convention consistent with this recommendation.
  2. For minor changes:
    • Don't change the namespace name in either the WSDL or the XML schema.
    • Add a sinceVersion attribute to the new elements in the XML schema. The sinceVersion value has the form MAJOR.MINOR and applies to all child elements until another sinceVersion value is encountered. We'll explain this is greater detail later.
    • If the minor change is due to the addition of an operation (and, consequently, the addition of new request and response messages), add a sinceVersion element to your payload. You can place it, along with some meta-information that you may already have, as part of your payload schema. You can omit this for the .0 release of the Web service and assume that whenever this element is not present, the version is MAJOR.0 until a sinceVersion attribute is encountered in the XML tree.
    • The value of the sinceVersion should be incremented for every minor change. For simultaneous changes, you can use the same value for the sinceVersion attribute wherever applicable.
    • Annotate the affected WSDL operation with the MAJOR.MINOR version number.
  3. For major, or incompatible, changes, change the namespace name of the WSDL and the namespace name of the XML schema documents to which the WSDL refers. The new namespace name should contain the new major version. When code is generated from this WSDL, it helps if the directory structure itself has the major version number as part of the source tree.

    Optionally, you may want to retain the sinceVersion information introduced during minor changes for historical reasons, if the new structure of the XML allows that.

  4. For all changes, major or minor, store the combined version information for the WSDL, MAJOR.MINOR, externally, for example, using UDDI or WebSphere Service Registry and Repository, or by annotating the WSDL.

This approach is illustrated in the sample application and described in the following section.

Implementing compatible changes to a Web service

The challenge in making compatible changes to a Web service is two-fold:

  • The changes have to be accomplished within the constraints of the business requirements, which may often force a major incompatible change.
  • Wherever possible, compatible changes have to be accomplished within the constraints of XML schema 1.0, which is the de facto method of describing the format of the SOAP payload.

The following sections describe three different approaches for managing service evolution, and the advantages and disadvantages of each approach. These three approaches are

  • Compatible XML schema design approach
  • Service adapter approach
  • Maintaining multiple versions

Compatible schema design-based approach

As described earlier, for compatible evolution the schema of the request messages has to change in a backwards-compatible manner and the response has to change in a forward-compatible manner. This implies that service providers should ignore the absence of additional data they may have introduced as they evolved. There are a variety of ways to achieve this within XML schema. The simplest is to add an optional element.

Implementing forward-compatible response message changes is a bit more interesting because older requesters have to successfully consume newer messages that they have never seen. Fundamentally, all we need is an optional placeholder in the response message that older requesters are designed to ignore, as shown in Figure 3 from a schema validation perspective.

Figure 3. Evolution of the response message
Figure 3. Evolution of the response message
Figure 3. Evolution of the response message

However, the actual implementation of this strategy within the constraints of XML schema 1.0 gets a little tricky. An XML schema 1.0 constraint known as the Unique Particle Attribution constraint (UPA) causes some complications. To understand this issue in detail, refer to the O'Reilly article, Extensibility, XML Vocabularies, and XML Schema. Because of this constraint, the simple structure shown in Figure 3 doesn't work.

One way to get around this constraint is to have nested placeholders, as shown in Figure 4. This gives us the result we want because there is always a placeholder for the next enhancement and it is consistent with XML schema 1.0. However, it leads to some readability issues with nested elements in the schema. This approach is based on a forward-compatibility approach that is covered in detail in the O'Reilly article, Extensibility, XML Vocabularies, and XML Schema for the evolution of XML languages. Note that XML schema 1.1 has relaxed the UPA constraint, which leads to a simpler schema design. However, for the purposes of this article, we'll stick with schema 1.0.

Figure 4. Creating a forward-compatible schema using XML schema 1.0
Figure 4. Creating a forward-compatible schema using XML schema 1.0
Figure 4. Creating a forward-compatible schema using XML schema 1.0

Creating a forward-compatible schema using XML schema 1.0

Complete the following steps to create a v1.0 schema, as shown in Listing 1:

  1. Define the response schema as a complexType with appropriate elements. This is the responseType. The element with type responseTypethat will be used for the WSDL part is not shown here.
  2. Add an optional element in the complexType as a placeholder. In our example, this is AdditionalInfo of type AdditionalInfoType1.
  3. Define AdditionalInfoType1 as a complexType with an optional any element. That any element belongs to the targetNamespace. We now have v1.0 of the schema.
    Listing 1. Version 1.0 of the response message
    <complexType name="responseType">
    <element name="info" type="…"/>
    <element name="AdditionalInfo" 
    type=" AdditionalInfoType1" minOccurs="0"/>
    <complexType name="AdditionalInfoType1">
    <any namespace="##targetNamespace" processContents="lax" 
    minOccurs="0" maxOccurs="unbounded"/>

Now you need to create v1.1 of the schema and change it in a forward-compatible manner. As you can guess, it's time to provide a concrete implementation of AdditionalInfoType1 . Complete the following steps, as shown in Listing 2:

  1. Add a container element called newInfoContainer as the first element in AdditionalInfoType1. Add additional 1.1 elements, such as moreInfo to the new container element.
  2. To track when this change was introduced, add an attribute called sinceVersionwith a fixed value of 1.1 to newInfoContainer, as shown in Listing 2. This attribute allows you to easily track changes both at the schema and the SOAP message level.
  3. Next add a placeholder for the next change to AdditionalInfoType1. Call it AdditionalInfo as in v1.0, but make its type AdditionalInfoType2.
  4. Define AdditionalInfoType2 just like you defined AdditionalInfoType1 in v1.0.

    In Listing 2, you can see that a reference to the placeholder AdditionalInfo is nested within AdditionalInfoType1.

    Listing 2. Version 1.1 of the response message
    <complexType name="AdditionalInfoType1">
    <element name="newInfoContainer" minOccurs="0">
    <element name="moreInfo" type="…"/>
    <attribute name="sinceVersion" type="string" fixed="1.1"/>
    <element name="AdditionalInfo" 
    type="AdditionalInfoType2" minOccurs="0"/>
    <complexType name="AdditionalInfoType2">
    <any namespace="##targetNamespace" processContents="lax" 
    minOccurs="0" maxOccurs="unbounded"/>

You can use this approach to make all elements in your schema extensible by introducing placeholders at the end of the element definitions. Notice that we use ##targetNamespace for the AdditionalInfoTypeX. This allows changes to the response schema to belong to the same namespace as the original response schema.

In summary:

  • This was a compatible change, so the namespace name did not change.
  • New elements were assigned a version number using a fixed value attribute.
  • In the WSDL, an annotation was provided under the operation name to describe the change, and to track the latest version of the WSDL. The WSDL sample illustrates the annotation.
  • You can track the version number using UDDI or WebSphere Service Registry and Respository.

Advantages of this approach are:

  • The strategy is based on the service provider WSDL. The only understanding required beyond what is described by the WSDL is that messages with the same major version are compatible.
  • Compatibility checks can be enforced using schema validation.

Disadvantages are:

  • The response schema can be difficult to read.
  • The additional nesting may have performance implications.
  • It requires careful planning starting with at least the first version of a major release, if not the first release of the service itself.

Tools support

This approach may not work with many Web service tools, but we've tested the approach with the following:

  • Apache Axis 1.x
  • Rational Application Developer V6.0.1.1 WebSphere Web Services runtime with interim fix 003A
  • WebSphere Process Server V6.0.2 with WebSphere Integration Developer V6.0.2

Service adapter approach

The first version of an XML schema is often designed and deployed without evolution in mind. Things go well for a while, until it's time to make a change. At that stage, most people tend to make incompatible changes even when a compatible change is possible. In cases like this, you can use a service adapter if the following are true:

  • There is enough information in the old request message to transform it to the new request message.
  • There is enough information in the new response message to transform it to the old response message.

We recommend coding the service adapter using XSL stylesheets and using an ESB to transform the SOAP payload. In this case, Figure 5 shows how an older request message from a v1.0 requester are processed by an XSLT engine and transformed into a v1.1 request message, which can then be consumed by the v1.1 service. The opposite is done for the response message, where the v1.1 response from the service is transformed into a v1.0 response message. In an SOA scenario, it's expected that an ESB is present to execute these transformations.

Figure 5. Using XSLT to transform SOAP message payload
Figure 5. Using XSLT to transform SOAP message payload

Advantages of this approach are:

  • It works even when evolution was not originally planned for in the schema.
  • A single latest version of the service can be maintained.
  • Content can be enhanced to any degree, because a stylesheet can invoke other services, make database calls, and so on.
  • It's relatively easy to write stylesheets.

Disadvantages are:

  • It requires a tool that can apply an XSLT stylesheet to the SOAP XML. This is not a problem if you have an ESB, but is a little harder when you don't. For JMS-based Web services, you can use WebSphere Application Server V6 to write a mediation handler that can apply an XSLT stylesheet to an incoming request message. See A practical introduction to message mediation for more information. Another approach is to have a composite service with one service serving as the adapter.
  • The contract, or WSDL, of the service, doesn't convey the fact that the service may be compatible with older service requesters. One solution is to create two separate endpoints for the service, one with the older WSDL, which invokes a stylesheet as part of the request processing pipeline, and one with the newer WSDL, using an ESB, for example.
  • Software-based XSL transformations can significantly slow down response time, especially if the XML documents are large, because they need to get parsed an extra time by the XSLT engine. If performance is a concern, you can use an SOA appliance like IBM DataPower, which executes XSL transformations much more quickly.
  • The additional overhead of maintaining the XSLT stylesheets can be considerable. Changes to the service WSDL and XML schema and the service implementation necessitate XSLT changes. Over time, if there are n versions of the requesters, one for each minor version of the service as it evolved, n-1 stylesheets may have to be maintained.

Recommendation: Use this option only if the XML schema-based compatible evolution approach doesn't work you.

Maintaining multiple service versions apprpoach

A third option is to simply maintain multiple versions of the service and configure the requesters to talk to the appropriate service versions using content-based routing through an ESB, for example. The advantage to this is simpler design with minimal impact on the service requesters. The disadvantages is that it is expensive to maintain multiple services versions if maintaining a single latest version is an option. In our experience, these multiple versions of the same service end up with a very similar code base, and bug fixes and code updates typically have to be applied to each of the versions. Also, additional hardware may have to be provisioned, and additional software licensing may be required to host these "near" copies.

Recommendation: Use this option only if the compatible schema evolution and XSLT-based approaches are not feasible.

Summary of recommendations on the various approaches for compatible evolution

  • Our recommendation is to use the compatible XML schema design approach, because it has minimal impact on your infrastructure, since you don't need to create XSLT stylesheets, maintain multiple versions of services, and so on. It also allows schema validation of messages in all phases of service evolution.
  • If compatible XML schema design is not possible, for example, if the first version of the XML schema was designed without evolution in mind, use an XSLT adapter-based approach until the next major revision. At that point, use the compatible XML schema design approach.
  • If either of these approaches is not feasible, maintain multiple versions.

Evolution and versioning of services that don't use WSDL or XSDs

The best practice approach we've suggested work for document-oriented Web services. The specific approach illustrated in this article on compatible schema design is based on XML schema 1.0. In cases where messages are not SOAP-compliant, but still defined using XML schema 1.0, these guidelines are still applicable for the most part. In cases where a service doesn't use XML, you can develop an approach suited for the specific message format as described below. The fundamental idea is to have placeholders in the message definition for unknown content on the response side.

About the sample application

The sample application included with this article is the commonly used Stock Quote Web service. In this example, the service evolves as follows:

  • In v1.0, the service receives a stock symbol and returns its price.
  • In v1.1, the service is enhanced in two ways:
    • Service requesters can send an additional optional parameter to the service to indicate that they want real-time quotes instead of standard quotes.
    • The service returns some additional information, namely, the minimum and maximum value of that stock on the previous day.
  • In v1.2, the service is further enhanced so that, in addition to the minimum and maximum stock values introduced in v1.1, it also sends some earnings-related information to the service requesters.

The service requester and service provider teams agree that these enhancements will be available only to those requesters that upgrade and that older requesters that do not upgrade will continue to function normally.

The sample application includes both the client- and server-side code for all three versions, 1.0, 1.1 and 1.2. Stubs were created using Axis 1.3 and tested in Apache Tomcat V4.1.34. Request and response SOAP messages for all three versions are also included, as are detailed instructions for running the sample.

WebSphere Service Registry and Repository and service governance

We've discussed a few techniques you can use to achieve compatible service evolution. While these techniques are useful, they must be effectively enforced. Without efficient governance processes in place, the guidelines and the versioning strategy may be ignored until it's too late. It helps to have a service rollout process in place with appropriate approval steps. Besides governance, it's also important to have an enterprise wide repository of service metadata that contains the appropriate XML descriptors, such as the WSDLs and XML schema documents. Many companies use a UDDI registry to address such needs. A more recent development is WebSphere Service Registry and Repository, which helps with SOA governance. Service Registry and Repository is less abstract than UDDI in the sense that it understands typical Web service artifacts, such as the WSDL and XML schema, and can, for example, automatically figure out dependencies. Following are just a few of the things you can do with Service Registry and Repository:

  • Define a service lifecycle using a workflow with a built-in approval process so that a service moves through various states, such as created, approved, and operational.
  • Perform automatic impact analysis of a change by inspecting the WSDL and XML schema imports and listing dependencies.
  • Create user-defined dependencies between various artifacts.
  • Subscribe to changes. The queries can be fairly complex to cater to the needs of various groups with different levels of interest in different types of changes.
  • Associate a version with every physical artifact, such as a WSDL and XML schema. You can use this version number, which can contain any user-defined version identifier, in conjunction with the versioning technique described in this article to allow the version number to become available at in the service registry as well.
  • Store artifacts such as WSDLs and XML schema documents.

For more information on Service Registry and Repository, please refer to Introducing IBM WebSphere Service Registry and Repository.


In this article, we've proposed a possible Web service evolution and versioning strategy. Although you can modify this strategy to suit your specific needs, the proposed strategy contains all the ingredients to meet most common Web service evolution needs.

Specifically, this article covered:

  • The meaning and importance of compatible evolution.
  • Guidelines for service evolution in the context of Web services.
  • A Web service versioning strategy for both compatible and incompatible changes.
  • Three techniques for compatible evolution: XML schema based, XSLT-based, and maintaining multiple service versions.
  • A brief introduction to service governance and WebSphere Service Registry and Respository, an IBM product that helps with SOA governance.


The authors would like to thank Adam Sohn of JP Morgan Chase, and Greg Flurry and Kyle Brown of IBM for sharing their insight on versioning and their comments on this article. We'd also like to thank Joseph Sharpe and Russell Butek of IBM for reviewing this article.

Downloadable resources

Related topics


Sign in or register to add and subscribe to comments.

Zone=WebSphere, Business process management
ArticleTitle=Designing and versioning compatible Web services