views:

281

answers:

3

So I'm a bit new to web services and a situation recently came up where we added an element to a data-type that gets returned to the client. The clients complained that this broke their implementation because it choked on the new element that it did not expect. (we are providing the services via Axis2).

To me this seems like a harmless change that the client should be able to handle gracefully (I've worked with some non-web-service frameworks where adding optional information was completely acceptable). I could understand if we deleted or renamed some fields that that would cause issues for the client.

Basically I would expect the wsdl to act like an interface. If we make a change that essentially subtypes that interface, I would expect the client to happily ignores extraneous elements. Is this just a short coming of web services, or is there a sane way of making passive changes to the services so that new clients can get the extra data while old clients can update at their leisure?

+2  A: 

In the past, when dealing with exposed WebService APIs, I've always gone with the date-versioning philosophy. Unfortunately, you have to deal with backwards compatibility for any API you release to the public once you're out of "beta" mode (and sometimes even then).

What we did was really simple; on the day the new API was released, we'd create a folder structure like so:

http://mydomain.com/path/to/service/2009/12/17/servicename.svc

That way we would know which version was the latest just by checking the folder structure, and our clients wouldn't have to worry about breaking changes until they were ready to upgrade. Worked like a champ for us; the only thing I might have changed was to use a single folder so they'd be easier to view all together:

http://mydomain.com/path/to/service/2009-12-17/servicename.svc
jvenema
I do something very similar do this, except I prefer to use explicit version numbers (e.g. http://http://example.com/ServiceName/1.0/Service/ ) and bumping it ONLY if the API changes in a non backwards compatible way.
Iain Collins
+3  A: 

WSDL actually acts as a contract more than an interface. The WSDL describes exactly what the operation expects to "receive" and what it expects to "return". The closest analogy to this would be in C changing the prototype for a function without changing the function itself, they wont match and that causes problems.

The more specific the WSDL is the more behavior you are "guaranteeing" to be in place.

If you need flexibility in your returned data (i.e. adding/removing fields etc) you can do one of the following:

  1. Version your WSDL definitions and publish services that can redirect older versions to newer versions
  2. Use more abstract data return types, such as XML to hide the complexity or changing data.

2 has some more risk, but it can be managed with XSDs or other technologies. Your particular project requirements will dictate what is acceptable.

GrayWizardx
A: 

A WSDL is effectively your published SOAP interface of your web service. Many clients use this to generate their client proxies that expose all your webservice methods in their programming language of choice. Most of these code-generated clients are very fragile and will choose to throw an exception if they see an element they don't recognize (i.e. its not in the WSDL) rather than ignore it. Some are more relaxed and it is really up to the client technology they use i.e. Microsoft's new DataContract's have IExtensibleData interface on their clients to specifically hold data they don't recognize so they will largely ignore unknown elements.

SOAP and code-generated client proxies lends itself to these kind of problems because they generate clients that want to understand 'the entire schema' rather than just the bits they are interested in. The alternative is for them to use an Xml Parser and just pull out the bits that they need.

If your web service is under development or constant change then SOAP is really not your best choice as it will mean with every change they will have to regenerate, rebuild and redeploy their service clients. Depending on your situation you may want to consider providing REST+POX (Plain Old Xml) web services instead as its simpler to parse as it doesn't have the overhead of SOAP, can be called via a normal URL and by consumed by environments that don't have a SOAPClient library (e.g. directly in a browser, using AJAX)

mythz
I must disagree with the above as I've never had problems with additional elements in the request/response using PHP's SOAPClient, C# (Mono/.NET) or Perl SOAP libraries or with JavaScript (I would note there is at least one pretty good cross browser SOAP client in JavaScript). REST options for publicly facing interfaces are valuable tools for things like mashups but SOAP is a better programmatic approach for web services.
Iain Collins
Lain, if your using a SOAP client then you're not using WSDL generated code, all your doing is using an intelligent Xml parser to skip past the SOAP headers to get to the payload (of course you're not going to get parser errors with a dynamic language). If this is the case then exactly what benefit is the added perf overhead and complexity of the SOAP web service?
mythz
Your premise is invalid as SOAP clients do use WSDL generated code, they just don't tend to throw errors when extraneous elements are present. They almost all work like this in practice. This in no way negates the advantages of using SOAP because the boiler plate *should* all be automated. As such, I would counter is very easy to implement (unless you using something horrible and deprecated like the RPC/Encoded format, which is what gives SOAP a bad reputation for complexity).
Iain Collins
Lain you were talking about the PHP (http://php.net/manual/en/book.soap.php), Perl (http://www.perl.com/pub/a/2001/01/soap.html) or JavaScript Soap Clients none of which use generated code. I have spent a large part of my career developing with WSDL generated SOAP clients (developed a webservices fx: servicestack.net). I can tell you for certain that any significant change (renamed elements, modified namespace, unexpected ordering, etc) does throw serialization exceptions. You can't just refactor a SOAP service and expect existing clients to work - its the nature of the beast.
mythz
Btw, if you are using auto-generated boiler code then *you are having to* redeploy your clients, this is not the case if you're parsing the Xml or using Xpath to pull out only the parts you are interested in and they haven't changed - that is the point I'm trying to make.
mythz
Actually PHP, Perl and C# .NET/Mono clients most assuredly do use the WSDL to auto-generate interface code, and they do not break due to additional elements being accepted (but not passed to) a Doc/Lit web service (only the JS client does not use the WSDL because it's a hack). To quote, "extraneous elements" is what is being discussed here. No one is entertaining the idea that renaming elements is going to be fine (though re-ordering shouldn't cause any problems in any half way sane implementation, and I very doubt it does in practice given I know most clients ignore superfluous elements).
Iain Collins