Dare makes a few comments about one of my previous posts so I thought - in true blogsphere fashion - I'd follow-up in a new post. First I'll mention a few more things about versioning web services, then I'll get to Dare's comments.
Versioning web services can be very challenging depending on the results you're trying to achieve. The primary decisions revolve around compatibility. First scenario, the easy way out: no compatibility. If you choose this route, it is highly recommended you implement a breaking change so your intentions are clear. So, for the next version of your service, you change the namespace, create a new endpoint address, and (re)deploy the clients for that service. When I said the easy way out, I was referring to versioning ... obviously not maintenance and deployments.
As you can imagine, there are a number of forces that can mandate a service implement a breaking change. The most common of these is driven directly from the business. The recommendation I make about using a single parameter for Web Service operations is strictly for the scenarios when we're applying a non-breaking change. We should always strive for compatible changes when we want to avoid the maintenance and deployment headaches evidenced above. I think most of this was understood in my previous posts, but I wanted to state it explicitly just to be clear.
I think it's also important to make a distinction between different kinds of Web Services, even if they're broad and sweeping. There is a considerable difference between a service-oriented Web Service and one that is not service-oriented. Perhaps my choice of GetTemp( TempRequest ) was a poor one. Service-oriented operations are very course-grained because they represent a business process. Because of this, the service interface is not likely to change (unless the organization is going to stop offering the service). However, the data pieces that service will require could very possibly evolve over time. Therefore, it's important to be able to version the service interface and the parameters of the operations independently. If you agree at this point, then we need a way to identify what version of the operation's inputs are being used. The only way to accomplish this with multiple parameters is for one of the parameters, which has nothing to do with the business logic of the operation, to contain version information. With a single parameter, we can maintain a straightforward experience for the client developer. Consider this message schema:
<s:schema ... targetNamespace="urn:service"> <s:element name="param" type="tns:UberParam" /> <s:complexType name="UberParam"> <s:sequence> <s:element name="param1" type="s:string" minOccurs="0" /> <s:element name="param2" type="s:string" minOccurs="0" /> </s:sequence> <s:attribute name="version" type="s:string" use="required" fixed="1.1" /> </s:complexType> </s:schema>
Just for completeness, the C# version of this parameter will look like this.
using System.Xml.Serialization; [XmlType( Namespace="urn:service" )] public class UberParam { public string param1; public string param2; [XmlAttribute()] [System.ComponentModel.DefaultValue( "1.1" )] public string version = "1.1"; }
By providing a fixed value for the version of the data type, the service developer has more metadata to work with and the client developer can focus on only the job at hand.
UberParam uber = new UberParam(); uber.param1 = "value"; uber.param2 = "value"; MyService.Operation( uber );
Depending on the requirements, a Web Service acting more in the role of a traditional API might not need this level flexibility. In these cases, I still recommend a single parameter, but without the need of additional metadata, the recommendation is less founded.
From Dare ...
Also the developer has to know how to manage interdependencies between properties of the TemperatureRequest that are set if there are any that are mutually exclusive, know which properties are required and whether to initialize primitive values in the object to defaults without any help from the API.
These issues are valid whether we have one parameter or multiple. The developer is still required to know something about the API and its requirements.
The other reason I like the former [multiple parameters] is that it carries the impression that the XML Web Service end point is unchanging while the latter [single parameter] does not.
As a client developer, I would find more comfort by feeling a single-parameter service is constructed in a flexible enough way to withstand the pressures of evolution.