This page attempts to cover basic versioning patterns in web services. A lot of these patterns can be mixed and matched to provide the best combination.
No Version Pattern
Description: Some people may choose to not worry about versioining at all. While, not strictly a versioning pattern, it is helpful to mention this to know the upsides and downsides.
Pros: Easy.
Cons: Old clients built on the previous version will break.
When to use: when you have total control over every client using your service.
References: None.
Namespace Pattern
Description: Namespaces can be used to determine different type versions. Your first service revision may have a target namespace of "urn:company:service:v1" and each subsequent major revision will have an increased version number. Knowing the version of your xml documents, will tell you which version of the service to invoke.
Example:
Say you want to move from a decimal type for prices (which allows a minimum of 18 digits beyond the decimal point) to a more approciate price type which you created which only allows 2 digits beyond the decimal:
Old Version:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" <soap:Body> <Price xmlns="urn:company:service:v1">3.333333</Price> </soap:Body> </soap:Envelope>
New Version
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" <soap:Body> <Price xmlns="urn:company:service:v2">3.33</Price> </soap:Body> </soap:Envelope>
Because of the namespace change you know that the first request is still acceptable even though it doesn't conform to your latest schema.
Services following this pattern: Amazon
Pros: Takes advantage of XML namespaces, works well with backwards incompatabile schema changes.
Cons: Doesn't take advantage of XML schema extensibility.
When to use:
References:
- Designing Extensible, Versionable XML Formats (Very very good)
- Versioning XML Vocabularies
Version Parameter Pattern
Description: Including a version number in the request will help you determine how to process the request and what kind of response to return.
Examples:
Example 1 (Header):
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" <soap:Header> <Version xmlns="urn:company:service">340</Version> </soap:Header> <soap:Body> .... </soap:Body> </soap:Envelope>
Example 2 (Body):
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" <soap:Body> <SomeRequest xmlns="urn:company:service"> <Version>340</Version> .... </SomeRequest> </soap:Body> </soap:Envelope>
Services following this pattern: eBay (header)
Pros: Uses XML schema extensibility.
Cons: Does not work well with incompatabile schema changes, doesn't take advantage of XML namespaces, requires users to pass the parameter in ever request.
When to use:
References:
Endpoint Pattern by specifying a Custom XFire Servlet Controller
Web service URLs (endpoints) follow an arbitrary convention, for example, version 1.0.0 of a service called SportsService would have a URL like:
http://myhostname.com/services/1_0_0/SportsService
In order to accomplish this you must override XFireServletController.getService(HttpServletRequest). A custom XFire Servlet controller can be specified by overriding XFireServlet.createController(). It is in your implementation of getService() that you can establish how your URL will map to a service.
The following code snippet illustrates this pattern. The complete example may be viewed at:
http://arsenalist.com/2007/03/01/web-service-versioning-with-endpoints-using-xfire/
Overriding XFireSpringServlet to create a Custom XFire Servlet Controller:
public class CustomXFireServlet extends XFireSpringServlet { public XFireServletController createController() throws ServletException { return new CustomXFireServletController(getXFire(), getServletContext()); } }
Overriding the getService(HttpServletRequest) method to establish a URL to service name mapping.
public class CustomXFireServletController extends XFireServletController { public CustomXFireServletController(XFire xFire) { super(xFire); } public CustomXFireServletController(XFire xFire, ServletContext servletContext) { super(xFire, servletContext); } protected String getService(HttpServletRequest request) { String pathInfo = request.getPathInfo(); String serviceName = ..... // parse service name out of pathInfo return serviceName; } }
New Endpoint Pattern
Description: The new endpoint pattern is very close to the version paramter pattern. The only difference is that instead of putting the version being accessed into the request, it becomes part of the URL being invoked.
Example:
http://example.com/service/v1 http://example.com/service/v2
Services following this pattern: JIRA?
Pros: Uses XML schema extensibility.
Cons: Requires users to update their invocation url each you update versions, Does not work well with incompatabile schema changes, doesn't take advantage of XML namespaces.
When to use:
References:
