Saturday, March 31, 2012

REST versioning, an example

It's not exactly news anymore that the most appropriate way to handle versioning of a REST API is by using the Accept and Content-Type headers.  A simple example would be:

GET /customer/1 HTTP/1.1 Accept: application/vnd.mycompany.myapp-v2+json

Notice that we are using a vendor MIME type since this is not any kind of JSON, it's v2 :)

The important thing is that we always have one URI to represent our resource and still can version it appropriately. A URI expresses identity and therefore it doesn't change when a new version is introduced.

Still, some people insist in handling versioning using the URI. This would give us:

GET /customer/v2/1 HTTP/1.1

This is pretty bad because you end up having different URIs pointing at the same resource which could be a maintenance headache. The version is leaking into the interface when it should not. 

To sum it up: the Accept header solves the versioning problem for GET and the Content-Type header solves it for POST so use them.

I have created a simple example of REST versioning using Groovy, Jersey and REST-assured that shows this concept in action.