The only thing that we know for certain about the future is that things will change, and that is especially true in our industry. If your APIs are successful they will be used in ways you never had foreseen and the data you deliver will be combined with other data in very surprising ways.
At the same time technology will change and what your organisation can and want to deliver to its customers will change. In order to keep relevant and to keep serving these ever evolving needs and requirements your APIs need to change and you need to know how to handle these changes.
API Versioning & Version Life Cycle Management
The most common way of handling changes its to have versions of an API. Additions to the API as well as changes that do not break existing code using the API (which is very uncommon) can be handled within one version. If there are breaking changes, i.e. that risks breaking code that is using the API, these should be introduced in a new version of the API.
Any new version should be announced to the developers in plenty of time for the community to have opportunity to test it and give feedback on it before the features are set in stone and the API version goes into production. Once in production the new version should be run concurrently with the older version of the API in order to give all developers time to migrate their code to the new version. In time the old version will be deprecated and stop working.
This whole version life cycle needs to be done in close cooperation with the developer community since there are real risks of destroying trust with any version update. By communicating with and listening to the community this risk can usually be handled quite well.
What should be versioned?
Should the API be versioned as a whole or should individual resources or groups of resources be versioned? The smaller the unit is to be versioned separately the more complications you will create for yourself and for the developers using the API. If resources are versioned separately it needs to be very clear what version of what resource plays together with what version of every other resource. In most cases this quickly becomes over-complicated and painful.
If different parts of the API need to be versioned separately for some reason I recommend that you split your API into two separate APIs with their own versioning. In that case the two smaller APIs have to be able to live independent of each other so that you do not have to handle the “what version of A plays well with what version of B” game. In short it is recommended to have one versioning scheme for your whole API.
How to version an API
The most common way of versioning an API is to include the version number in every URL. For example:
- http://api.linkedin.com/v1/people/~ – where /v1/ means that this call is to version 1 of the LinkedIn API
- https://api.twitter.com/1.1/statuses/home_timeline.json – where /v1.1/ means that this call is to version 1.1 of the Twitter API
The advantage of this is that the version is right there in the URL, easy for everyone to see and use. There will never be a question about which API version the request was meant for.
An alternative solution is to set the API version in a custom HTTP Header, such as “X-API-Version”. This is more in line with the REST specification but comes with it’s own drawbacks. The main problem is how to handle requests that does not set the version header – do you then return an error or do you use the latest version of the API? If you automatically use the latest version of the API – how do you then handle breaking changes when introducing a new API version?
Personally I prefer having the version number in the URL itself, but mine and your personal preference are irrelevant. It is what the users and potential users of your API want that matters, so if you are in doubt ask them. After all if they are unhappy they will not use your API and happy users are more important than any personal taste or to follow any specification to the letter.
Is Versioning the Perfect Solution?
The simple answer is no since there are no silver bullets or single solutions to any problem as complicated as changes in an API. There are pros with versioning, the most significant is that you know how to handle future changes even if you do not yet know what those changes are. However, there are also cons, such as:
- Depending on the size of the user base and the nature of apps using the API any version update can be extremely painful. This is especially true if the API is used in device firmware that it might be impossible to update efficiently or if the API is used by a large number of mobile apps that can be very hard to update on a massive scale. To mitigate this the old and the new version have to live in parallel for a long time, maybe for the foreseeable future, which puts more stress on you as an API provider.
- Keeping several versions alive at the same time can complicate your code base quite a lot. Unless handled well in the back-end this is the start of good old spaghetti code with a serious overdose of if/else statements.
- Any version change, or for that matter, any major change, in your API will come with increased support costs and a risk to alienate developers. If developers have to do significant work to upgrade their app to the latest API version they might as well look for alternative solutions from competitors. This needs to be handled with support, well written documentation on how to upgrade etc, which again increases support costs.
This is all very gloomy and leads to the natural question…
Is there an alternative to versioning?
The alternative to versioning is to not introduce breaking changes. If you need to introduce potentially breaking changes you instead introduce these as additions to the current API. Instead of changing the data a resource type returns you instead introduce a new type of resource and have both resource types live forever side by side. Depending on how your API is used and the rate of change this might be your only solution.
Final words
Prepare for change and let everyone know how you will handle change. The key to handling changes in your API is to not surprise your users. If developers knows what is coming and have time to prepare for these changes you will have a much happier user base.
Please join in the discussion on this article over on Hacker News and reddit.
IMO in most enterprise situations, versioning has to be an assumption. In narrowly scoped APIs with very specific functionality, you can often avoid this complexity with a very good up front design. In my experience, having no versioning means shackling yourself to early mistakes.
Great post!
Glad you like the post 🙂 I agree that versioning should be the first choice unless you have very good reasons to go another route.
— for future readers — (I should start a blog series “For future readers of APIUX.com”)
These are not all, and IMO not the recommended, alternatives. I am upfront about the possibility, or I should say probability, of being in gross minority, albeit that’s neither/nor a dis/advantage.
In short, one alternative is:
– use custom (vendor) media-types (( one day, when mature or when enough consensus is reached, someone will register them and they will become a standard – i.e. application/singly-profile+json ))
– version the media-types
I can add that this is not about preference, but the reasoning is long enough not to be part of this comment. Just for the record, this is not the same with the X-API-Version alternative.
I don’t think my analogy at http://andreineculau.github.io/hyperrest/2013-03-30-rest-api-concepts/ is perfect, but should be good enough to see that versioning the API/resources doesn’t make sense.
But more of this, when I get the time to write, Andreas 🙂 Thanks
PS: if it’s not obvious, wherever the version is omitted, one has to default to the first/oldest possible version, in order to maintain backward compatibility the longest. IMO that’s like shooting yourself in the leg; the simplest thing: *require* a version, despite the *inconvenience* crap you’ll hear.
Bruno, hook this guy up with an account so he can write some posts!
I already invited him but he says he doesn’t have any free time. Go figure.
I will do some loobying on your behalf on this. I would love to see Andrei write more full blog posts instead of long comment rants. He is a really smart guy that knows what he is talking about.
Pingback: Do you really need API Versioning? | CodingScoo...
Pingback: API Måndag – events events events » API – Mashup.se
One week later, at least 1 other person agrees and writes in detail about the alternative mentioned in my previous reply.
http://urthen.github.io/2013/05/16/ways-to-version-your-api-part-2/
You should probably also want to read part one of that article (http://urthen.github.io/2013/05/09/ways-to-version-your-api/) which explains different ways to version an API.
Pingback: Reading List « function(arg)
Pingback: Dew Drop – June 10, 2013 (#1,564) | Alvin Ashcraft's Morning Dew
Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1374
Pingback: Dew Drop – June 11, 2013 (#1,565) | Alvin Ashcraft's Morning Dew
Pingback: Weekly Web Roundup - June 14 2013 Don't Believe The Type
Pingback: How to design APIs that last | API UX