2

Trying to understand versioning with SOAP and web services. From what I have found it seems acceptable to do something like this with the URL:

www.company.com/service/01-12-10/ and www.company.com/service/03-08-10/ and www.company.com/service/ support the latest version.

I understand this is the way to go as opposed to just versioning the SOAP body/payload like this:

[client]

someRequest = newRequest(){ ClientVersion = "1.0.0" };
webService.Go(someRequest);

[web service]

if request.ClientVersion == "1.0.0"
  do this code
else
  do this code

I can see how all the conditionals will get out of hand as changes are made AND that this does not handle the case when a web method's signature is removed. Most importantly, however, this is not versioning the entire service, just the body.

So, my question is did I get it right by just changing the URL to include the version? Does this enompass all the necessary areas? It just seems like I will have some namespace conflicts? Is it necessary to change the namespaces too? Trying to understand what it means to version the service. Please expand.

O.O
  • 11,077
  • 18
  • 94
  • 182

1 Answers1

7

Having the client send a version parameter is usually not preferred because you can't count on the client to send the proper version number (if you have multiple versions of your web service you can end up receiving a payload for version X but marked with a version parameter value Y).

For this reason it's better to enforce the version with the namespace of the contract schema, something like:

...
<types>
      <xs:schema xmlns="http://tempuri.org/v1"
                targetNamespace="http://tempuri.org/v1">
...

When you make breakable changes to your contract (like removing an operation) you break all your existing clients which is a big NO NO to do because you basically make your web service un-callable, thus useless.

So when you have a major version change you expose a new contract that you now define like:

...
<types>
      <xs:schema xmlns="http://tempuri.org/v2"
                targetNamespace="http://tempuri.org/v2">
...

You continue to support v1 for existing clients while using v2 for all the new clients to come (and luckily, with time your v1 clients can migrate to v2).

When you need to support multiple versions, you basically need to manage endpoints. At this point you can go two ways.

You either maintain one endpoint like www.company.com/service/ which receives all messages (v1 and v2) and acts as a facade to redirect to the proper implementation based on the message namespace or...

... you directly expose the versions as separate endpoints and the existing clients will use an old endpoint that receives v1 messages (maybe www.company.com/v1/service/) while new clients use another newer endpoint that receives only v2 messages (maybe www.company.com/v2/service/).

The above setup is easier on your (only one) business implementation which is exposed to clients through different skeleton implementations of your web service. The skeletons for v1 and v2 transform their specific payload parameters into appropriate parameters for the business layer. In this way all calls converge into the business layer who at this point normally doesn't care which version the client was.

Hope it's more clear now...

Community
  • 1
  • 1
Bogdan
  • 23,890
  • 3
  • 69
  • 61