URI

Why do I even care what version your API is? Versioning your API with HATEOAS

Original image by zenera

I HATE OA(R)S. Original image by zenera

This is another in my unofficial series on stuff to do with REST. You can see the others by clicking here for API Anti-Patterns or here for Cookies and the RESTful API.

Notice what I did there? Think hard. I linked some other documents that you can GET. Click’em and you’ll:

GET: http://blog.mikepearce.net/2010/08/24/cookies-and-the-restful-api/

What I did there was provide you with two hypertext links, one to each of the other posts about REST that I’ve written. This is HATEOAS. You see, ¬†you don’t actually need to know those two links above to be able to find them, you don’t even really need to know this link to THIS blog post, you only need to know my endpoint, which is http://blog.mikepearce.net. Navigate to there, and then you can get to each and every other page on my blog without having to know the URLs.

Even if you DID know my URLs (and by ‘know’ I mean bookmark, only the most diehard Mike Pearce fans memorise all my blog post URLs, dontcha Jon?) I might, one day, decide to change the schema, so they wouldn’t work. However, you’d get a 404 and a list of possible URLs, or I might even 301 redirect you if I was feeling nice (and this wasn’t hosted on wordpress.com). The thing about this hypermedia is that it’s so easy to get anywhere you like, the very definition of surfing.

CAN HAZ ENDPOINT. (Image by kwerfeldein)

So, now you’ve had a short tutorial on what HATEOAS means, Hypermedia As The Engine Of Application State, essentially means that your clients shouldn’t be building their own URIs. They should be requesting one of your endpoints and retrieving a list of URI with which they can interact with with one of the HTTP verbs (GET, PUT, DELETE, UPDATE, POST). The idea (which I illustrated above) is, that as an API provider, should you need to, you can change your URIs when you like and your clients will still know how to access all the resources of your API (if they’ve written their client to support that kind of thing). You could get away with one endpoint, the root of your API URI scheme. But it might be nice to provide one or two more which aren’t every going to change, perhaps:


http://api.yourcompany.com/users


http://api.yourcompany.com/links

Further, you can then provide your users with a list of properties that the API response will return at each of these endpoints, that links to the URIs they need to access to interact with your service. So, if the user were to:

GET: http://api.yourcompany.com/users

The response might be:

{
	"userMutateActions":
	{
		"add": "/users/add",
  		"update": "/users/updateUser",
  		"delete": "/users/deleteThatSucka"
  	},
  	"userReadOnlyActions"
  	{
  		"get.Details": "/users/$username",
  		"get.Email": "/users/$username/email",
  		"get.Dob": "/users/$username/dob
  	}
}

Now you’ve a contract with your clients that means they can visit any of the three endpoints and be able to navigate their way around the rest of your API. If you were a nice API provider you could provide examples of code for your clients to integrate into the software that interrogated your API for these endpoint URI indexes…

You see, I think that here it is a little fuzzy. The idea is that a client can and should be able to bookmark a URI it knows about and be able to call that URI and have your API still respond is one of the tenets of a REST API, but it’s at odds with HATEOAS.

Eggheads and Philosopers (Image by Dunechaser)

Eggheads and Philosopers (Image by Dunechaser)

Anyway, that’s for eggheads and philosophers. Use your best judgment to decide when and where to do this kind of thing, how many endpoints you have and what you provide as URIs to your clients.

I should really get to the point described in the title. But you’ve probably worked it out by now…

There are a couple of ways of versioning an API, check out slides 88 – 93 of my presentation in the API AntiPatterns presentation here, either on the URL, or in the body of a request or with primary and secondary URIs. The thing is, after I wrote that and while I spent a bit of time reading more about cookies, I decided that none of those methods of versioning were any good, the answer is…

… don’t actually bother with versioning. If you’re adhering to the HATEOAS contraint and you’ve created some good, solid endpoints, some documentation that creates contracts as to nomenclature of your URI properties with your clients, then you don’t need to version. Just change the URIs and the values of the URI properties at each endpoint and the client won’t even know you’ve done it.

Shhh, it’ll be our little secret!