How To Version Your REST API

So the other day I was playing with writing a new REST API. Everything was going great until I decided that I wanted to try changing the structure of a certain resource (say, change the response for resource at /user/1 from {name: jason} to {username: jason}). I had a number of integration tests, but figured I could migrate my integration tests incrementally, just like third party applications would have to do in the real world. I just had to be able to respond to requests for both versions. This immediately raised the question: “How do you version your API?

If you spend just two minutes with Google, you’ll find that this is a question that gets asked a LOT, and has different answers depending on whom you ask.

In the URL!

One way to version your API is to put a version in your URL, such as mysite.com/v1/thing/id. You’d be in good company. Atlassian does it like that. Google does it too. A format like this is easy to recognize and easy to test.

This is the most highly voted approach from the popular StackOverflow question. And this is a common sentiment in Hacker News: “I can’t recall a single API I’ve seen or used that took the academic approach of using HTTP Accept headers. All of the major REST APIs I’ve seen have used API key X-* headers and most of them use versioned URIs.”

In the Headers!

Putting version information in the HTTP Accept header (so the client says what they can Accept, and the server responds with the appropriate Content-Type) seems like a pretty common answer. It seems to be accepted as the “more correct” approach at the expense of being more academic and less practical. There are even well reasoned arguments why this is the best way.

At first I was wary of this approach because I worried about not being able to detect the header in the request logging, and so wouldn’t be able to tell when to retire the old service. But it turns out you can log requests and record header information, especially if you are fronting with apache.

They’re All Wrong!

Ok, so we have a couple approaches (not to mention using query parameters), but there is a third approach: they’re all wrong. When this big question of how to version a REST API came up to Roy Fielding (inventor of REST), his response was “Don’t.”

According to Fielding: “You can’t have evolvability if clients have their controls baked into their design at deployment. Controls have to be learned on the fly. That’s what hypermedia enables.”

Where Do We Go From Here?

My opinion at this point in time is to use the Accept Headers for content negotiation rather than put version information in the url or query parameters. It just seems like the right way to do it and is easy enough on client and server.

The question for you is: How do YOU version your API? Is it possible, as Roy Fielding implies, to write a versionless API where every field is purely discoverable? I’m skeptical but would love to be shown a better way.

Advertisements

Leave a comment

Filed under Software Engineering

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