05/18/08 :: [REST] Versioning [permalink]

|

I like to argue that "Versioning" is the most important concept in SOA. Your SOA is doomed to fail if you are not careful about your versioning strategy.

Why? the reason is quite simple. A Service is a reusable IT asset, a SOA is an architecture that enables you to build solutions from reusable assets. As services gets reused, their ability to change becomes seriously impacted.  A service cannot easily change because not every consumer can evolve at the same time, they don't have the money, the resources, they are not ready to take the risk...

Service versioning is also key because "Governance" is by definition imperfect. Don't get me wrong, Governing your services is the right thing to do. However, you can only do so much with Governance to predict what future consumers will need to consume based on the service that you need to build now. Ultimately, and most likely, you will version your services to increase the consumer base. Do you plan on operating one service (version) per consumer? hopefully not, SOA would be useless if this was the case.

Web Services (as in WS-*) support a very sophisticated versioning strategy fully aligned with service reuse. This versioning strategy relies mostly on the extensibility mechanism of XML and XSD, so one would think that REST would be able to benefit just as well.

Stefan has avoided discussing "versioning" because indeed REST does not have a great versioning strategy. I friendly reminded him last fall that encoding the version in the URL was not viable. Peter agrees.. At least, that's something I understand. Peter provides some tips and tricks that amount to an alternative solution based on Media Type negotiation (and the capabilities of XML and XSD). Unfortunately, Peter, your approach to versioning is still incomplete.

Let's look at why. The reason is because you need a service versioning strategy that creates both forwards compatible (Peter, this is called forwards compatible, not backwards compatible) services and backwards compatible versioning and you also need a versioning strategy that decouples endpoints and versions for operational reasons.

The difference between forwards and backwards compatibility has been explained extensively. You need both, though one might argue that forwards compatibility is a tiny bit more important (the kind that Peter mislabels as backwards compatibility). Backwards compatibility is when the consumer comes in with a "newer" request version than the service provider can provide. This is common when a consumer uses different providers for the same type of service. So ultimately, you need to provide some room to define the version of both the consumer and the version of the service provider that it is targeting. Your mechanism only supports "one version".  

The other problem I see is that ANY REST versioning strategy couples, by definition, the endpoint and the version. This can be a problem. This is actually a general flaw in REST (as a programming model for SOA, Roy designed REST for completely different purposes). Let's say you built a service Sv1 and you serve 1000 requests per day. Now, a new consumer comes along and wants you to serve 1 M requests per day. This might require a completely different infrastructure. I know this is not an insurmountable problem and I am sure some router can use the media type to route the request, but now you really have broken the "global scope" of a URI, I mean a single URI does not point to the same thing, the media type is part of resolving the real endpoint.

Another flaw of your versioning strategy is that URIs are by default part of the versioning strategy. I have often pointed out that "Query-by-examples" are encoded by members of the REST community (MORCs) in a URI syntax, for instance:

/customer/{id}/PurchaseOrders ...

Peter, how do you express that a particular QBE belongs to one version and not to the other?

You will soon start realizing that resources do have a state that is independent of the "application" since by definition a resource can participate in multiple "applications". This is the essence of SOA, i.e. the essence of reuse. At least you are one of the most lucid MORCs I know of:

A URI that is constructed by a client constitutes a permanent, potentially huge, commitment by the server. Any resource that may be addressed by the constructed URIs must forever live on that particular server (or set of servers) and the URI patterns must be supported forever.

Effectively, you are trading a small one time development cost on the client side for an ongoing, and ever increasing, maintenance cost on the server side. When it is stated like that it becomes obvious that URI construction introduces an almost absurd level of coupling between the client and server.

Yes, Peter, we agree, a URI is an "Identifier", nothing else, nothing more. You conclude:

Using hypermedia as the engine of application state has the effect of preserving the reversible for a huge number of decisions that are irreversible in most other architectural styles.

which is of course absolutely true in Roy's world -the Web- but completely "absurd" in SOA. It is not surprising that you find media types as the key to REST versioning. This is the essence of WSDL contracts, add some operations and you would have reinvented WSDL.

Peter, you seem to be close to understanding that resources interact with each other. Since you seem to have quite an open mind,  have you ever considered these two scenarios (interactions and resource-side state?).

If you consider these two scenarios you will be so close to WS-* that there won't be any noticeable difference between how to use REST in SOA and WS-*.  (Again, REST, the way Roy defines it, is a completely different thing and was never designed to be applied to SOA).

So sure, MORCs can keep adding semantics (I really mean tips and tricks) to Roy's REST but ultimately they'll remain tips and tricks, i.e. particular point solutions interpreted slightly differently by different people.

At least, some of the MORCs could have the courtesy to acknowledge that they are indeed building a programming model on top of REST, that this programming model needs clear semantics and that these semantics are not intrinsically part of REST (nor always RESTful).