The value of Service-Oriented Architecture (SOA) (See Resources) as a modern approach to integrating computing system components is widely recognised. Web services provide a common, open-standard basis for communication between those system components. The Web services protocol is suited to both intra- and inter-enterprise integration. A key objective of SOA is loose coupling between components. Loose coupling enables components to change aspects of their behaviour without impacting other components. While this is a valuable objective, in reality there will still be many changes within a single component that require change in other components.
This article provides a process for identifying the types of changes that will impact Web service consumers and those that will not. It discusses a number of strategies for dealing with changes that do impact consumers and to provide criteria for selecting the most appropriate solution. A significant criterion will be the cost of solution options, and it is recommended that you carefully assess the benefits and costs of a solution before you apply it to your particular business scenario.
A significant portion of the article offers detailed instructions on the use of Rational® Application Developer to implement changes to Web services to help reduce the impact on both service providers, and service consumers.
Current Web services standards have little or no support for managing change. This article aims to provide a set of change management best practices for Web services.
Backward compatibility refers to a hardware or software system that can use interfaces and data from earlier generation(s) of the system. In the context of Web services, backward compatibility is concerned with how changes to an interface affect existing users (otherwise known as service consumers) of the interface. If existing users are unaffected then the change is backward compatible. If existing users are affected then the change is not backward compatible, and a strategy will be needed to manage the impact of the change.
The concept of backward compatibility is closely related to the concepts of change and change management. No matter how carefully we design our Web services, there will be situations where the interface needs to change. The change needs to be made in a planned and systematic fashion, and it needs to be done according to a staged approach. The typical stages in managing change to Web services are:
- Assess if the change is backward compatible
- If not, assess if support for the old interface is required
- If yes, design and implement the change so that both the old and the new interface are supported concurrently
- Decommission old interface after a pre-defined grace period
The backward compatibility assessment, stage 1, is examined in the next section.
The stage 2 assessment is in the business management domain. A hard cutover to a new service or the decommissioning of an old interface, even with a grace period, may lead to severe business disruption. Since this decision-making process is in the hands of business management, it is outside the scope of this article, which is primarily aimed at the development team.
The rest of the article examines several versioning techniques for supporting old and new interfaces concurrently (stage 3) and an approach for decommissioning the existing interface (stage 4). In this last discussion, we use the concept of deprecation. We declare a Web service to be deprecated when it will be decommissioned after a certain period of time.
Several papers have been published on the subject of classification of backward compatible versus backward incompatible changes (See Resources). The aim of this section is to consolidate and complement the earlier discussions.
Some changes can be accommodated in a way that is completely transparent to the service consumers using an existing interface. Let's consider the following example interface, and in the ensuing discussion some changes which might occur:
- Web service URL:
- http://bigbank.com/BigBank/services/AccountService
- Operations defined as follows (using notation
output_message operation(input_message):accountNumber create(name, street, suburb, postcode, state)amount deposit(accountNumber, amount)amount withdraw(accountNumber, amount)amount balance(accountNumber)
Many changes can be made to the interface that do not impact existing users, as follows:
- Adding a new operation
- Existing consumers will continue invoking existing operations while new operations become available for new consumers. Existing consumers are unaffected.
- Example: Adding operation transfer is a backward compatible change
amount transfer(fromAccountNumber, toAccountNumber, amount)
- Adding new optional data structures to the input message
- The existing consumers are unaffected since they will be unaware of the new data structures.
- Example: Adding optional field
countryto the create operation as followsaccountNumber create(name, street, suburb, postcode, state, country=null)
- Changing cardinality of existing input data structures from mandatory to optional
- The existing consumers continue using input data structures as if they were mandatory. Existing consumers are unaffected.
- Change to the service provider implementation which has no material impact to the interface
- Service implementation can be modified or totally rewritten as long as there is no material impact to the interface. That is, the existing interface specification is fully supported.
A range of changes will immediately "break" existing consumers:
- Removal of an operation
- The old interface is no longer a proper subset of the new one. Existing consumers using the removed operation will be impacted.
- Example: Removal of the operation
amount transfer(fromAccountNumber, toAccountNumber, amount)will break consumers using it. This change is not backward compatible.
- Changing cardinality of existing output data structures
- Change to the cardinality of fields in the output message, such as changing mandatory fields to optional fields, will break existing consumers.
- Change to the definition of data types
- Most changes to the data types in the input or output message are not backward compatible.
- Example: Something as simple as changing decimal to float data type will break existing consumers.
- Business rules or business process changes
- Sometimes there is a dependency between Web service operations. This dependency typically arises because operations must be invoked in a prescribed order. Should the underlying business rules or business process change, the dependency changes and the existing clients no longer operate correctly even when the interface remains unchanged or is changed in a backward compatible manner.
- Example: Let's assume the Big Bank decided that a withdrawal can only be executed if it was previously authorized. Naturally, we have to introduce a new operation like this:
boolean authorize(accountNumber, amount). According to our previous discussion, this change would be backward compatible. In this case however, the change is not backward compatible as the existing consumers using thewithdrawoperation are broken because they will not be invokingauthorize.
There are cases where the change will not impact existing consumers, but some adverse effect may occur. It is recommended that the service provider assess each change in this category on a case-by-case basis in respect to its backward compatibility.
- Change in quality of service (QoS)
- Should the service provider implement change in a way that does not affect the interface but adversely affects qualities of service, such as response time and availability, it will have an adverse effect on existing consumers.
- Changing assumed domain of values in the output message
- Consumers may have an expectation about the domain of values of certain fields in the response message. If the provider starts returning values outside that assumed domain, it will likely have an adverse effect on the existing consumers.
- Example: We restrict
AccountNumberwith<xsd:pattern value="[0-9]{12}"/>meaning the account number is a string exactly 12-digits-long. Leading zeros are allowed, however our original implementation never returns leading zeros. If we want to change our implementation resulting in the possibility of having new account numbers created with leading zeros, it could be detrimental to some consumers.
Methods of versioning Web services
If a backward incompatible change must be made to a service, but both the old and the new version of the service must be available, then some means of supporting both the old and new interface is needed.
All methods of versioning described here allow a new interface to be introduced to a Web service without requiring the removal of the existing interface. They each have different impacts, which will affect their suitability in any particular scenario. In all versioning approaches, it is worthwhile changing the namespaces of the schema types to prevent type confusion between different versions.
If you need to introduce a new version of an operation within a service that will not work for existing consumers, consider versioning by operation. You can maintain backward compatibility by creating a new operation based on the old one and keeping both in the interface. You continue to make the early version of the operation available. This results in a backward compatible change to the Web service, which allows both the old and new version of the operation to coexist.
For example, a change may be required to the Account.create operation to allow it to accept country as a mandatory input. This can be done without affecting the existing operation by adding the following new operation:
Account.createV2(name, street, suburb, postcode, state, country)
Providing the implementation of the original create operation remains intact, then both the old and new version of the operation may be consumed.
Although this method of versioning is simple to implement and isolates the impact of versioning to a single operation, it has several disadvantages. It couples the Web service more closely to the implementation code, as both operations must now be implemented within the same Web service, making future removal of the operation more complex. This could lead to an abundance of operations within the same Web service if more versions are introduced. Also, if a change is required that affects multiple operations within a Web service (such as a change to a data type shared by multiple operations) versioning by operation can quickly become unwieldy.
Versioning by Web service name
Versioning by Web service name has a larger impact than versioning by operation as it affects the entire Web service rather than a single operation.
For example, given an existing Web service AccountService, a new service may be defined with a different name, such as AccountServiceV2. New or changed functionality may be implemented for the operations in AccountServiceV2 without affecting the existing AccountService Web service. Unchanged operations would also be implemented by AccountServiceV2, so the old AccountService could be removed when it was no longer needed.
Introducing a new Web service to provide versioning has the advantage that the changes are isolated from the original implementation. If at some point the earlier version needs to be removed, the entire Web service can be removed rather than having to excise code on a per-operation basis.
A disadvantage is that the versioned Web service name may find its way into the generated implementation code, depending on the Web services development toolkit used. This means that with each new version, differently named sets of objects may be created, requiring additional work for consumers to integrate them into existing code.
When versioning is performed by URL or endpoint, the URL of the endpoint is changed, rather than the operation or Web service name.
For example, if the existing Web service is located at the following URL:
- http://bigbank.com/BigBank/services/AccountService
A new version may be introduced at the following URL without affecting the existing Web service:
- http://bigbank.com/BigBank1/services/AccountService
This new version contains a complete set of operations with the required changes, so that a consumer would use either one or the other URL exclusively to access this Web service. With this method of versioning, as the names of the Web services and operations remain the same, the amount of change required to upgrade a consumer to make use of the new version is likely to be less. The impact on generated code will be less than other methods.
As the change occurs at the context root, the new interface is again independent of the existing interface. It requires that a separate Web module be created for handling requests on the new URL. Versioning by operation or by Web service name do not require a separate Web module.
Decommissioning the old interface: When and why?
Maintaining multiple versions of the same service can become an expensive proposition. Table 1 compares costs between making backward compatible changes and backward incompatible changes that employ versioning.
Table 1. Costs of backward compatibility vs. backward incompatibility with versioning
| Cost | ||
|---|---|---|
| Service provider activity | Backward compatible change | Backward incompatible change mitigated by versioning |
| Design and development | Similar in both scenarios - costs will depend on the complexity of the change | |
| Progression testing of the new interface | Similar in both scenarios | |
| Regression testing of the old interface | Small | None |
| Incremental deployment | None | Some additional (multiple versions will generally introduce additional deployment effort) |
| Maintenance (e.g. finding and fixing defects) | Lower (defects need to be fixed only once) | Higher (defects need to be fixed in two or more versions) |
| Decommissioning of the old interface | None | Small (deletion of the old version(s)) |
| Service consumer activity | ||
| Design and development to adopt new interface | None | Some additional (will depend upon complexity of the change) |
| Progression testing of new interface | None | |
| Deployment | None | Some additional |
The table above indicates that backward incompatible changes with versioning are more expensive than backward compatible changes. Furthermore, the cost increases proportionally with the number of versions supported.
On the other hand, if a backward incompatible change is introduced without versioning, existing consumers will no longer work. Organizations who depend on the service face business interruption, potential loss of revenue, and/or penalties.
Clearly, a balance needs to be found between no support and endless support for the old interface. The following approach is recommended:
- Once a new version of the service becomes available, the old version is declared deprecated, indicating that it will be decommissioned after certain period of time.
- Consumers must be notified about deprecation of a service, to allow them time to change and test the consuming code. Service decommissioning of an old version requires a reasonable notice period, typically three months or more.
- No more than two versions of a service should be operational at any time. Supporting more than two versions is not only expensive for the service provider, but also delays realization of the business benefits that instigated the change in the first place.
- While two versions are available, toggle between the two versions.
All methods of versioning provide a means of concurrently supporting multiple definitions of one or more Web services. In theory, any number of versions of a Web service may be supported using any of the methods outlined above. However, for the reasons just stated, it is generally recommended than only two versions of the same service be maintained at a time.
To manage two instances of a service, we propose toggling between one version and the other while introducing the new version. Toggling employs versioning by URL.
For example, let's assume two versions of the same service. The current versions are all available under the following base URL:
- http://bigbank.com/BigBank/services/
We may have the following set of Web services:
- http://bigbank.com/BigBank/services/AccountService
- http://bigbank.com/BigBank/services/CustomerService
- http://bigbank.com/BigBank/services/EmployeeService
If a new version of AccountService is required in a release, then using versioning by URL we might now also have the following service:
- http://bigbank.com/BigBank1/services/AccountService
But the previous version of the Web service would also be retained, and we would have URLs for the complete set of Web services for both versions:
- http://bigbank.com/BigBank/services/AccountService <- Old version
- http://bigbank.com/BigBank/services/CustomerService
- http://bigbank.com/BigBank/services/EmployeeService
- http://bigbank.com/BigBank1/services/AccountService <- New version
The original service is still available on the original URL. The new service is available on a new URL.
So far, this is identical to simply versioning by URL: a new version of a Web service is introduced, and so a new URL is created. However, let's consider another release where further changes are made. Let's assume that we now want to make another change to AccountService, as well as a change to CustomerService. With toggling, rather than introducing a new URL for the second new version of AccountService, we will toggle back to the original URL. URLs for the new set of Web services after the next release will be:
- http://bigbank.com/BigBank/services/AccountService <- New version
- http://bigbank.com/BigBank/services/CustomerService <- Old version
- http://bigbank.com/BigBank/services/EmployeeService
- http://bigbank.com/BigBank1/services/AccountService <- Old version
- http://bigbank.com/BigBank1/services/CustomerService <- New version
Since only two versions of a Web service are required at any time, the original URL may be reused. This restricts the number of Web modules that are required. We don't end up with an abundance of base URLs (context roots) or version numbers, all existing versions are contained within two URLs.
The example shown above allows two supported versions of a Web service. In exceptional circumstances (such as an imposed regulatory change or bugfix change), the concept can be extended to allow any number of concurrent versions by extending the set of valid context roots (BigBank2, BigBank3, etc). You could also consider using other context root naming conventions, such as BigBankA, BigBankB.
An obvious implication of this approach is that service consumers must be notified as to which context root contains the latest version of a particular Web service. These details are typically captured in release notes. It also limits the availability window for the old Web service, so Web service consumers are forced to upgrade to the latest version before the next release.
For the Big Bank example used in this article, we have used versioning by URL and toggling. This allows the implementation of the new interface to be separate from the existing interface and it provides the benefit of reducing the number of Web modules required. The next section of the article provides sample implementation details.
In the following sections we will show how to implement versioning by URL. The example we will use is the AccountService Web service described earlier. The following WSDL and XSD files describe the interface for the AccountService Web service:
- Types.xsd
- Account.xsd
- BankFault.xsd
- AccountService.wsdl
Types.xsd contains the low-level type definitions of Address, DollarAmount, and AccountNumber. Account.xsd contains the request and response schema definitions for the AccountService Web service operations. BankFault.xsd contains the exception type for the all operations and AccountService.wsdl contains the Web service definition.
The Big Bank wants to expand into other countries but the Web service definition for the Account.create operation does not allow a country as part of the Address type in the request. They also want to allow a backward compatibility window for existing Web service clients to migrate their applications to the new Web service definition, so the existing Web service definition must also be supported in parallel.
In this example we use IBM Rational Application Developer Version 6.0.1 to create the new Web service while maintaining the existing service unchanged.
The Web service operation Account.create needs a new mandatory parameter for country, so we modify the Address type to add this new field. We also create a new namespace for this type to exist in, so it does not clash with the existing definition and there will be no confusion between the old and new version of Address. We add the year and month to the namespace as this is the de facto standard for versioning of namespaces.
We create a new version of Types.xsd with the changes highlighted in bold in Listing 1.
Listing 1. New version of Types.xsd to support country names
<?xml version = "1.0" encoding = "UTF-8"?>
<xsd:schema attributeFormDefault="qualified"
elementFormDefault="qualified"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://parts.bigbank.com/2006/03"
targetNamespace="http://parts.bigbank.com/2006/03">
<xsd:complexType name="Address">
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="0" name="street" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="suburb" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="postcode" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="state" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="country" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="DollarAmount">
<xsd:restriction base="xsd:float">
<xsd:pattern value="[0-9].[0-9]{2}"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="AccountNumber">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[0-9]{12}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema> |
Now we need to create a new version of Account.xsd to use this version of Types.xsd. So we modify the namespace in the Account.xsd file and leave all the type definitions in the file. We do this as the request and response messages are specific to the Web service and we are creating a new version of the whole Web service so it makes sense to create new versions of all the request and response messages.
Listing 2 shows a snippet of the Account.xsd file with the changes highlighted in bold.
Listing 2. New version of Account.xsd to support country names
... <xsd:schema attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://parts.bigbank.com/2006/03" targetNamespace="http://parts.bigbank.com/2006/03"> <xsd:include schemaLocation="Types.xsd"/> ... |
Finally we create a new version of the WSDL file. We modify the namespace for the Web service with the date version and also modify the endpoint. This is the endpoint that our Web service consumers will use to access the new version of the Web service. Listing 3 and Listing 4 provide two snippets showing the WSDL changes, again highlighted in bold.
Listing 3. New version of AccountService.wsdl - namespace changes
... <wsdl:definitions name="AccountService" targetNamespace="http://account.services.bigbank.com/2006/03" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://account.services.bigbank.com/2006/03" xmlns:intf="http://account.services.bigbank.com/2006/03" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="http://parts.bigbank.com/2006/03" xmlns:tnsf="http://faults.bigbank.com/2006/03" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <wsdl:types> <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://faults.bigbank.com/2006/03" schemaLocation="BankFault.xsd"/> <import namespace="http://parts.bigbank.com/2006/03" schemaLocation="Account.xsd"/> </xsd:schema> </wsdl:types> ... |
Listing 4. New version of AccountService.wsdl - endpoint change
...
<wsdl:service name="AccountService">
<wsdl:port binding="impl:AccountSoapBinding" name="AccountService">
<wsdlsoap:address location="http://bigbank.com/BigBank1/services/AccountService"/>
</wsdl:port>
</wsdl:service>
... |
Now that we have completed the new version of the WSDL we have to decide how to package the application so both the old and the new version of the Web service can exist side by side. Let's assume that the existing version is packaged as shown in Figure 1.
Figure 1. Packaging of the existing version of the Big Bank example application

BigBankClient is the third party client which uses the Big Bank Web services, BigBankWeb component contains the generated Web service code and its context root is set to BigBank. Finally the BigBankEJB component has the Account EJB which contains the business logic for the AccountService Web service.
The endpoint for accessing the new version of the AccountService Web service has a new context root so we need to create a second Web project with the context root of BigBank1. The new Web project will call a new function of the existing EJB which will implement the new business logic for the Web service. So the new packaging looks as shown in Figure 2.
Figure 2. Packaging of new version of Big Bank example application

Generating the new service provider Web service components
Once we have our high-level design worked out and we've made the required changes to the WSDL and XSD files, generating the new Web service provider components is reasonably straightforward.
The Rational Application Developer Web service wizards typically make some minor changes to WSDL and XSD files placed in the Web service deployment modules, so it is a good idea to keep these files in a separate project. As shown in Figure 3, we have placed our updated WSDL and XSD files along with the original files in a project named Build under Build/wsdl/schema200603.
Figure 3. Rational Application Developer Project Explorer showing the Build project components

As discussed earlier, we need a Web module with context root of BigBank1 to host the new version of the Web service. In our case this is the first time we have versioned the Web service, so we created a new Web module named BigBank1Web with the required context root. Next time we version the Web service we could toggle back to the original context root, BigBank. In that case we could use a similar process to generate the Web service provider components in BigBankWeb.
To create the Web service provider components, select the WSDL file at Build/wsdl/schema200603/AccountService.wsdl, and invoke the New Web Service wizard. We generated a Skeleton Java bean Web Service from the WSDL in the BigBank1Web project. It is a good practice to use the Wizard option called Define custom mapping for namespace to package. We created a mapping file Account-NStoPkg.properties to include the namespace year and month in the Java package names. This approach helps to avoid confusion between code generated from different namespace versions. You can see the generated Java packages in Figure 4.
Figure 4. Java packages generated by Rational Application Developer

Invoking the business logic from the generated Web service skeleton
AccountSoapPort.java is the generated Service Endpoint Interface and AccountSoapBindingImpl.java is the generated Java bean Web service skeleton. We need to add code to the generated skeleton to invoke the required business logic in our Account EJB. Because we have only added one extra parameter in the Account.create method the differences between the new AccountSoapBindingImpl.java and the old version are small. Defining imports for all of the generated classes helps to isolate the package name changes (due to the namespace changes) to the imports section of AccountSoapBindingImpl.java, as shown in Listing 5.
Listing 5. New version of AccountSoapBindingImpl.java - namespace change
... import com.bigbank.faults_2006_03.BankException; import com.bigbank.parts_2006_03.ACreateRequest; import com.bigbank.parts_2006_03.ACreateResponse; import com.bigbank.parts_2006_03.AWithdrawRequest; import com.bigbank.parts_2006_03.AWithdrawResponse; import com.bigbank.parts_2006_03.ADepositRequest; import com.bigbank.parts_2006_03.ADepositResponse; import com.bigbank.parts_2006_03.ABalanceRequest; import com.bigbank.parts_2006_03.ABalanceResponse; ... |
The other change is updating the call to Account.create to include the country field on the Web service request, as shown in Listing 6.
Listing 6. New version of AccountSoapBindingImpl.java - Account.create change
...
public ACreateResponse create(ACreateRequest request)
throws java.rmi.RemoteException, BankException {
AccountLocal account = createAccountLocal();
ACreateResponse response = new ACreateResponse();
response.setAccountNumber(account.create(
request.getCustomerName(),
request.getAddress().getStreet(),
request.getAddress().getSuburb(),
request.getAddress().getState(),
request.getAddress().getPostcode(),
request.getAddress().getCountry()));
return response;
}
... |
We used the Rational Application Developer Snippets view to generate the call to the local interface of the Account EJB. The Call an EJB create method snippet makes it very easy to invoke an EJB.
Of course the business logic changes required for the new Web service also need to be implemented. As described previously, we implemented business logic changes by adding a new create method to the Account EJB that accepts the additional parameter for the country and carries out the required processing. This way the old create method is still available for the old Web service, and both the old and new Web service versions make use of the same Account EJB methods for accessing all the unchanged business logic. The implementation effort focuses on the interface changes and business logic changes, maximizing the reuse of unchanged business logic.
At this point we now have two versions of the AccountService Web service available in parallel for service consumers. As described earlier, the old version of the AccountService is still available for use unchanged, but service consumers have been provided with notice that the old version is deprecated and will be decommissioned after the specified time period, typically at the next scheduled release. Service consumers need to update their Web service client applications to use the new version of AccountService before the old version is decommissioned. Let's take a look at what a service consumer would need to do to update their client application to use the new version of the AccountService.
Updating a client application to use the new Web service version
Our scenario does not use UDDI, as with many current Web service implementations. In this situation service providers typically provide service consumers with a Web site link where they can access the new WSDL and XSD files. The new WSDL and XSD for our Web service can be accessed in the Rational Application Developer test environment using the following link:
- http://localhost:9080/BigBank1/services/AccountService/wsdl.
For our scenario, we just used the Rational Application Developer Web Service Client wizard to create a Test Client application for the old Web service in the BigBankClientWeb module. To update this module to use the new version of AccountService, first open the Web Deployment Descriptor for BigBankClientWeb and remove the ServiceRef for the old AccountService, as shown in Figure 5.
Figure 5. Web Deployment Descriptor for BigBankClientWeb module

Then the generated components for the old Web service consumer need to be deleted. These components include the old WSDL and XSD files, the Web service client bindings files, and the generated Web service proxy classes, as shown in Figure 6.
Figure 6. Components to be deleted from the Web service consumer

As suggested earlier for service providers using Rational Application Developer, service consumers should also consider creating a separate project to keep the downloaded WSDL and XSD files that are used at build time. We invoked the New Web service client wizard with Build/wsdl/schema200603/AccountService.wsdl to generate a Java proxy in the BigBankClientWeb project. As for the service provider, use the Define custom mapping for namespace to package Wizard option to include the namespace year and month in the Java package names.
The last step is to modify the client application to use the generated new Web server proxy. As with the service consumer, this involves changing the client application to use the new packages names for the Web service proxy classes that resulted from the namespace change. The client application also needs to be modified to make use of the new interface. In our scenario, the client application needs to be modified to include the country when it builds the request message for AccountService.create.
Decommissioning the deprecated Web service
Once the deprecation window has ended, the final stage of our Web service versioning process can be completed. You can take any of a number of approaches to decommissioning or removing the deprecated Web service interface. A relatively easy way of disabling the Web service is just to comment out its servlet definition in the Web Deployment Descriptor (BigBankWeb/WebContent/WEB-INF/web.xml) as shown in Listing 7.
Listing 7. Commented out Web service servlet definition
... <!-- <servlet> <servlet-name>com_bigbank_services_account_AccountSoapBindingImpl</servlet-name> <servlet-class> com.bigbank.services.account.AccountSoapBindingImpl</servlet-class> <load-on-startup>1</load-on-startup> </servlet> --> ... |
However, to get the full maintenance benefits of deprecation and removal, you will want to do the refactoring needed to remove the Web service completely. In our scenario, the deprecated WSDL, XSD files, generated Java Web service skeleton classes, and Web service deployment descriptors, shown in Figure 7, need to be removed in the next release of the BigBank application.
Figure 7. Components to removed when decommissioning BigBank

If your Web module contains other Web services, then take care not to delete files or Web service deployment descriptor entries required by those Web services.
The business logic interfaces may also need to be tidied up. In our scenario the old create method on the Account EJB is no longer used so it can be deleted.
Using the approach described, your Web service clients have the convenience of a full release cycle timeframe to make any required changes to their applications. As a service provider, the approach allows you to support change that is not backward compatible in a sustainable way, without the need to carry on supporting the old interface indefinitely.
The techniques and guidelines for managing Web service change discussed in this article can provide valuable input to any SOA governance process. They show that development teams have a key role to play in implementing a change strategy that enables ongoing enterprise agility, through changing services, while minimizing the impact of that change on both providers and consumers. A strategy that provides predictability, recognizes that service changes need to be managed by the business, allows clearer communication of change and its potential impact, while improving the integrity and maintainability of the associated code.
Thanks to Peter Chilcott, Paul Dreyfus, and Charles Ray for their valuable review comments.
| Description | Name | Size | Download method |
|---|---|---|---|
| Zipped workspace | workspace.zip | 182KB | HTTP |
Information about download methods
Learn
- Patterns: Service-Oriented Architecture and Web Services, SG24-6303-00, Endrei M., et al. (IBM Redbooks, April 2004)
- Best practices for Web services versioning, Brown K., Ellis M. (developerWorks, January 2004)
- Make minor backward-compatible changes to your Web services, Butek R. (developerWorks, November 2004)
- Service Versioning - CBDI Journal Best Practice Report, Dodd J., Wilkes L. (CBDI, February 2006)
Get products and technologies
- Build your
next development project with IBM trial software, available for download directly from
developerWorks.

Mark Endrei is an IT Architect with IBM Application Services in Melbourne, Australia. His areas of expertise include Service-Oriented Architecture, Web services, and J2EE application architecture and delivery. You can contact him at Mark.Endrei@au.ibm.com.

Mario Gaon is a Senior IT Architect working for AMS Architectural Services team in Melbourne, Australia. He has extensive experience in integrating solutions across variety of technology domains including J2EE, COTS Packages and Data Warehousing platforms. You can contact him at mariogao@au.ibm.com.

Justin Graham is an Associate IT Architect who lives in Melbourne, Australia. He has worked for IBM since joining as a graduate in 1999. He specializes in Web services, J2EE applications and performance testing. You can contact him at justing@au.ibm.com.

Kerard Hogg is a Certified IT Architect with over 30 years experience in the Telecommunications Industry. Kerard specializes in Service-Oriented Architectures and has been lead architect on a number of significant engagements which made extensive use of Web services, J2EE and BPEL4WS in the Telecommunications industry.

Neil Mulholland is a Senior Technical Specialist working for AMS in Melbourne, Australia. He specializes in Web services, XML, J2EE technology, Websphere Application Server and object-oriented design. You can contact him at neilmulh@au.ibm.com.
Comments (Undergoing maintenance)





