About a year ago I was asked by a client to update their existing web service because of some changes in the way they wanted to process their sales data. Luckily this client has always understood the importance of a Service-Oriented Architecture ( SOA ) since they deal with large amounts of resellers who need to access, edit and create data. All I had to do was apply the changes to their web service.
I decided to move forward by using the following steps.
- Assess if the desired changes are backward compatible
- If not, assess if support for the old functionality is still required
- If yes, design and implement the changes so that both the old and the new functions are supported concurrently
- Decommission the old functions after a pre-defined grace period
Most of the changes were backward compatible but, as always, there were some obstacles. For some backward incompatible changes I was able to add optional data structures.
// Old function function create_account($name, $street, $postcode, $city) { ... // New function with added optional variable 'country' function create_account($name, $street, $postcode, $city, $country = null) { ...
For other functions I was able to call another function at the end of said function. This left pre-existing records untouched and, most importantly, the users of the webservices didn’t have to update their code.
Also some of the functions became obsolete so I decided to relay their functionality to newer functions and have them throw an exception stating that the function was replaced and soon to be deprecated.
The most important change however was making the decision to implement versioning for the clients web services. I advised the client to contact all it’s resellers via a mailing to inform them of the 1.0 version ( the version we had just updated ) of the web service. In the same mailing the client also mentioned it’s desire to update the service every 9 months and that every version of the service would be decomissioned 6 months after the introduction of it’s successor.
This made my job really easy because I only had to worry about backward compatibility for one version. Luckily almost every reseller went on this ‘journey’ with us. Of the 200+ users of the webservice only 3 didn’t update on time over the last year. Now I just implement all the desired changes once every 9 months and I provide the resellers with a detailed changelog and instructions for updating.
However, the most beautiful result of all is; a happy end for all parties involved.
looks like u got away with this pretty easy.
ive had to handle clients who would likely never be able to upgrade all with different versions.
this was handled by specifc default values for mandatory fields and through end points either being independent (for complex differences) or mutating through versions (1.1 endpoint using 1.0 and adding onto it and so on through a chain).
It went very smooth overall, indeed. Sometimes you’re just lucky.
For bigger non-backward compatible changes I like to use unique namespaces to clearly delineate the versions of a document that are compatible. You could also use UDDI to advertise compliance with several interfaces/functions. This even eliminates the need for a version number.
Our approach to solve this Problem is likewise
Our Service Endpoints have an Versionnumber
/services//servicename
And our Services are Classes and for every version a class extends the older version class
ServiceName_13 extends ServiceName_12
With this handling we can create new versions without coping source or touch old functions
Works very well for us.
I like the idea but how do you handle deprecated functions, do you just set them to private?
And how do you handle changes in data types for updated functions in extended services? In my opinion you could run into some database troubles this way, especially when your changes are too big.
Every Version has its own WSDL/XSD and removal of a function in the WSDL is automagical removal of the method from the service.
And till now we have no DB Problems