RESTful Versioning

I commented on RESTful versioning as a response to Peter William’s post on the same subject matter as I found it interesting. Because versioning is a fact of life and we can’t avoid it even though Subbu thinks we should, it’s imperative to always architect services with versioning in mind. Now that I’ve pondered over this a little bit, I think I get why getting this right is extremely important.

Part of architecting for versioning includes talking to potential (or existing) customers and figuring out what input/output of the service should look like. Never architect without involving the customer base. Having said this, it’s highly unlikely that the inputs/outputs will never change. Change is inevitable and this is why there must be a very good versioning solution.

Right now there seems to be two proposed ways of supporting versioning: via URIs and through the use of custom media types. When the client is the human web, URIs are really the only option. It’s with the programmable web that there may appear to be a decision to be made.

The Programmable Web

With the programmable web, choosing between the using Accept header and custom media types versus a URI becomes a little more interesting because of “hypermedia as the engine of application state” (HATEOAS). Consider the base representation of a resource with a URI of “http://order/123” that contains links to other resources.

<order>

<orderId>123</orderId>

<orderLine>http://order/123/orderLine</orderLine&gt;

</order>

Now imagine that the resources evolve independently of each other, such that there is a version 3 of “order” and a version 2 of “orderLine” yet the resources remain linked. From a programmable angle, if the the service uses a URI versioning scheme (http://v1/order/123), the service provider probably tries to ensure that the representations always contains the URIs for the right versions of its linked resources. It would probably be fair to assume that version 2 of order links with version 2 of orderLine but that is assuming that the resources actually evolve together which may not be case. Additionally, what if a consumer has evolved to version 3 of order but is still satisfied with version of 1 orderLine and cares for no other version? The service provider falls into the trap of trying to anticipate the versions of resources that a consumer wants. This almost impossible to pull off in a system that evolves – and most every system evolves.

With custom media types, the client is responsible for specifying the version of every single resource that they want. The service provider is not burdened with trying to figure out what version of application state a client will try to navigate. It defers that decision to client. It only needs to know how handle version requests. The client could ask version 3 of order by doing this:

Accept: application/vnd.mycompany.myapp-order-v3+xml

and for version 2 of orderLine, doing this:

Accept: application/vnd.mycompany.myapp-orderLine-v2+xml

A good versioning solution should allow the client to specify what version of a service/resource they want to reference at any given time.

Versioning in RESTful systems needs to be done outside of the URI if the system is to evolve and allow its clients to evolve with it. URI versioning doesn’t seem to be much of an option, am I mistaken?

Advertisements

About Ebenezer

culture hack. contrarian. change artiste. speaker. writer. silo-connector. entrepreneur. totally human. ff at your own risk. :-)
This entry was posted in Design and Architecture and tagged , , , . Bookmark the permalink.

One Response to RESTful Versioning

  1. Yep, I’ve come to the same result. media-types are the most reliable way to control versioning. My approach for the ‘human client’ (text/html) has been to automatically upgrade to the most recent version by mapping the custom media type and the text/html media type to the same resources.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s