views:

171

answers:

5

I am maintaining a SOAP web service (ASP.NET version 2.0) and I have to make some changes that will modify the return values of particular methods.

What is the generally accepted method of doing this without breaking existing implementations.

My initial thoughts are that the following would all be possible.

a) Provide new version specific methods within the existing web service e.g. getPerson_v1.4
b) Provide a complete copy of the .asmx file with a new version number e.g. http:/www.example.com/AdminWS_V1_4.asmx. This is not an idea I relish as the service has more than 50 methods and copying that code for changes to 2/3 methods seems like too much duplicated code.
c) Override the web-service constructor to allow passing in a version number. This does not seem to work, and on reflection I'm not sure how that would be represented within a WSDL

Is there a generally accepted way of doing this, or do people have advice based upon their experiences in this area.

+6  A: 

We deploy to version directories, for example:

http://www.example.com/soap/v1/ http://www.example.com/soap/v2/ http://www.example.com/soap/v3/

etc.

Lloyd
I think this is a good way of doing and many organizations use this method. This clearly shows that the user is accessing a different version of the service.
BobbyShaftoe
I would have included that on my list as it seems like a reasonable option however the Web Service sits in with a whole raft of other code and all of our existing users will be referencing the "Main" site (ie. without versioning)
Steve Weet
@Steve Weet, wouldn't that be solved by continuing the example and creating a directoy ala: http://www.example.com/soap/current/ - which would just map over to the newest version? Putting version numbers onto methods makes the API complicated for new users that are not interested in all the history...
Thies
@Thies. Yes it would, but I would have to get all my existing users to repoint to the existing versioned directory before I could deploy the new code. For historic reasons I don't have all of the contact details for these users.
Steve Weet
Users should and would want to point to specific versions that don't change in order not to break their existing code.When you deploy a new version then naturally they'd have to repoint but they're going to need to actually cater for changes in the new version anyhow so repointing is a trivial issue.
Lloyd
@Steve: You don't have to change your existing users. Just deploy the latest one to a versioned directory. Then publicly announce it. Everyone who wants to take advantage of the latest version will do so. Obviously at some point you will have to deactivate old versions. The easy way to alert people you don't know about is to just start throwing an error that says something like "Version deactivated. Please visit http://blah blah/ for more information" You can then get the contact details of the people who complain.. ;)
Chris Lively
This approach is probably the most common one that I've seen and does seem to be the easiest to manage. @Chris is spot on - since from the way you've described it anyone using the "new" version is going to require code changes - having them point to the new version at a new location isn't an issue. This lets you transition from the unversioned locations you use now to versioned ones over time.
sfitts
A: 

Unless you change most of the method signatures with each new version, I'd go with (a) - versioned method names. This is how our providers do it and it's working fine for us.

Marcel Popescu
+2  A: 

I've just thought of another possible solution which seems quite clean.

I could check for a version number included as a SOAP Header and assume the existing version number if this is not provided.

I can then make the code behave differently for different versions without changing the method signatures. This is possbile as the return values from the Web-Services are XML objects so the method signature remains the same but the content of the XML changes based on version.

Steve Weet
I'm personally not a big fan of this approach since it hides in the header something which really should be in the contract. Either the change you are making doesn't impact the contract for older callers (that is you can return the data in such a way that older callers will ignore the parts they don't understand) or it does impact the contract. If you are impacting the contract you should be explicit about declaring that fact (IMO).
sfitts
+3  A: 

In the general case, there's more to versioning a web service than just versioning method names and .asmx file names. Ideally, the interface to a web service (its WSDL) should be a permanent contract, and should never change. One of the implications would be that clients that do not need the changed functionality would never need to change, and therefore would never need to be retested.

Instead of breaking the existing contract, you should create a new contract that contains the changed operations. That contract could "inherit" from the existing contract, i.e., you could "add the methods to the end". Note, however, that you should also put the new contract into a new XML namespace - the namespace basically identifies the WSDL, and keping the namespace but changing the WSDL would be a lie.

You should then implement this new contract at a new endpoint (.asmx file). Whether or not this is in a different directory, or even on a different web site doesn't really matter. What matters is that clients who want the new functionality can refer to the new WSDL at the new URL and call the new service at its new URL, and be happy.

Be aware that one effect of changing an existing contract is that the next time an "Update Web Reference" is performed, you will be changing the code of the client proxy classes. In most shops, changing code requires re-testing, and redeploying. You should therefore think of "just adding methods" as "just adding some client code that has to be tested and deployed", even if the existing client code does not use the new methods.

John Saunders
+2  A: 

I have the same versioning issue with webservices that I am developing. We make our users pass a schema version number in the header. They tell us which version of the XML schema they want back. This way, we are always backwards compatible and code is not duplicated.

At my job, we cannot tell the client that they have to switch the URL to the webservice when we version it. In big corporations, changes as small as a URL could take months of testing. It is my feeling that you should not break your clients connection. What we do is, add new features to the latest version. When the client asks for the new features, if they want them, they are forced to upgrade to the newest schema.

Jon