I am currently working on a REST API, and the question was raised, how are, and how should, REST APIs be versioned? Here are the results of my research.
It seems that there are a number of people recommending using Content-Negotiation (the HTTP “Accept:” header) for API versioning. However, none of the big public REST APIs I have looked at seem to be using this approach. They almost exclusively put the API version number in the URI, with the odd exception using a custom HTTP header. I am at somewhat of a loss to explain this disconnect.
Versioning strategies in discussions
Post | Versioning | |
---|---|---|
Stack Overflow 1 | URI | |
Stack Overflow 2 | Content Negotiation | |
blog post by Jeremy | Content Negotiation | |
ycombinator discussion | some opinions both ways | |
Stack Overflow 3 | Content Negotiation | |
Stack Overflow 4 | Content Negotiation | |
notmessenger blog post | URI (against all headers) | |
Peter Williams | Content Negotiation (strongly against URIs) | |
Apigee Blog post on API versioning | URI (some discussion) | |
Mark Nottingham REST versioning | Recommending essentially versionless extensibility with a HATEOS approach | |
Nick Berardi on REST versioning | URI | |
Restify | “Accept-Version” header | |
Tom Maguire on REST versioning | Content Negotiation | |
Nicholas Zakas on Rest Versioning | URI | |
Steve Klabnik on Rest Versioning | Content Negotiation + HATEOS | |
Luis Rei on Rest Versioning | Content Negotiation with (;version=1.0) | |
kohana forum discussion on REST versioning | Many Opinions | |
Troy Hunt on REST versioning | Accept Header but also support custom header and URL | |
Paul Gear REST versioning | Recommending essentially versionless extensibility with a HATEOS approach |
Versioning strategies in popular REST APIs
API Name | Versioning | Example |
---|---|---|
Twillo | date in URI | |
URI | ||
Atlassian | URI | |
Google Search | URI | |
Github API | URI/Media Type in v3 | Intention is to remove versioning in favour of hypermedia – current application/vnd.github.v3 |
Azure | Custom Header | x-ms-version: 2011-08-18 |
URI/optional versioning | graph.facebook.com/v1.0/me | |
Bing Maps | URI | |
Google maps | unknown/strange | |
Netflix | URI parameter | http://api.netflix.com/catalog/titles/series/70023522?v=1.5 |
Salesforce | URI with version introspection | { “label”:”Winter ’10” “version”:”20.0″, “url”:”/services/data/v20.0″, } |
Google data API (youtube/spreadsheets/others) | URI parameter or custom header | “GData-Version: X.0” or “v=X.0” |
Flickr | No versioning? | |
Digg | URI | http://services.digg.com/2.0/comment.bury |
Delicious | URI | https://api.del.icio.us/v1/posts/update |
Last FM | URI | http://ws.audioscrobbler.com/2.0/ |
URI | http://api.linkedin.com/v1/people/~/connections | |
Foursquare | URI | https://api.foursquare.com/v2/venues/40a55d80f964a52020f31ee3?oauth_token=XXX&v=YYYYMMDD |
Freebase | URI | https://www.googleapis.com/freebase/v1/search?query=nirvana&indent=true |
paypal | parameter | &VERSION=XX.0 |
Twitpic | URI | http://api.twitpic.com/2/upload.format |
Etsy | URI | http://openapi.etsy.com/v2 |
Tropo | URI | https://api.tropo.com/1.0/sessions |
Tumblr | URI | api.tumblr.com/v2/user/ |
openstreetmap | URI and response body | http://server/api/0.6/changeset/create |
Ebay | URI (I think) | http://open.api.ebay.com/shopping?version=713 |
No versioning? | ||
Groupon | URI | http://api.groupon.com/v2/channels//deals{.json|.xml} |
Geonames | ||
Wikipedia | no versioning I think? | |
Bitly | URI | https://api-ssl.bitly.com/v3/shorten |
Disqus | URI | https://disqus.com/api/3.0/posts/remove.json |
Yammer | URI | /api/v1 |
Drop Box | URI | https://api.dropbox.com/1/oauth/request_token |
Amazon Simple Queue Service (Soap) | URI Parameter and WSDL URI | &Version=2011-10-01 |
Youtube data API versioning | URI | https://www.googleapis.com/youtube/v3 |
Versioning strategies in popular REST Libraries
Library Name | Versioning | Example |
---|---|---|
node-restify | semver versioning in an accept-Version header | accept-version: ~3 |
Jersey | description of how to do Accept: header versioning in Jersey | Accept: application/vnd.musicstore-v1+json |
The version of GitHub's API that you link to is deprecated. The new version v3 does its versioning via content negotiation whereas the old one had it in the URI. The new approach is documented here: http://developer.github.com/v3/mime/
BTW, I found this very useful. Thanks!
Pingback: How are REST APIs versioned? | Lexical Scope | nodeJS and Web APIs | Scoop.it
Pingback: How are REST APIs versioned? | Lexical Scope | Modern web development | Scoop.it
Pingback: How are REST APIs versioned?
Great list! I’ve also found the following article to be useful for API versioning strategies: http://blog.apigee.com/detail/restful_api_design_tips_for_versioning/
Pingback: REST Fundamentals | planetgeek.ch
This is usually due to header-mangling and stripping. Mobile ISPs, proxy servers, some regular ISPs – they actually strip out headers from HTTP requests. So while content negotiation is a principally sound and proper way to do it, the realities of the world we live in require putting the version in the URI.
Do you think it also has anything to do with people wanting to browse REST services in an ordinary web browser? I wondered if the difficultly of configuring the content-negotiation in most web-browsers might contribute to this.
Think about API requests from JS (end user browser).
I’m not sure I follow you. Are you saying it is easier to do it one way or the other from JS?
Luckily, meddling proxy servers can’t touch what you put through a TLS pipe. Performing all requests over HTTPS is a strong antidote against this. I’ve seen a big telephone carrier that downgrades all HTTP requests to HTTP/1.0, causing all kinds of fun caching issues.
Pingback: Revealing KijiREST: Resources | Kiji Community - Build Real-Time Scalable Data Applications on Apache HBase
another reason why URI based versioning isnt right…
http://bit.ly/14Vr4jc
http://abhishek.pamecha.me/blogs/versioning-in-web-services/
I think another reason is an implementation reason, because its easier and cleaner to have some web server work as a proxy to take /v1/ -> v1 service implementation instead of handling it in the service itself with a buch of ifs, like if(version==1) -> v1 of the service implementation
Pingback: REST Fundamentals | bbv Blog
Dont get bogged down by purists. Do what is simple, scalable and practical. Just because it may not fit a spec doesn’t mean it’s not better for your needs or your clients needs. After all, the biggest API users are using URI after all and they serve MILLIONs a day
Hello!
When an API is obsoleted, what do you do normally when you want to block an older version? What mechanism do you use?
Thanks.
you are talking about deprecation and you need to version both the api form and the api function; in other words, you need to do versioning on the api application as well as on the apiObject that establishes how the api request/response is handled for each related uri.
Pingback: Decoupling API Versions From Codebase Versions | Haddad's Journal
Found out after much reading that there is a good reason not to do versioning in header. forwards will not send header information properly and so it will often get lost. This is why alot of people after evaluation have stayed with versioning in the URI
If that is the case then the forward is not being performed correctly. You would lose authorization, language, media types, etc.. Version belongs in the accept header. i.e. I accept this media type and this version.
Pingback: El mekki anouar | API Versioning – Different Approaches to API Versioning (1)
Pingback: RESTful APIs | LibreNMS development blog
Pingback: Designer une API REST | OCTO talks !
Pingback: Make Breaking Changes without API Versioning | zhengziying.com
Pingback: REST y el versionado de servicios | Adictos al Trabajo
Pingback: Shaun Abram » Blog Archive » Versioning APIs
Pingback: REST API Versioning | onehundred15
Pingback: How to design a REST API | OCTO talks !
Pingback: API versioning methods, a brief reference
Pingback: Working with Microservices in an Ideal World - WanariLeaks
Pingback: על המגבלות של REST – בשירות מערכות ווב בנות-זמננו – בלוג ארכיטקטורת תוכנה
Pingback: Web API 版本控制的几种方式 - 算法网
Pingback: What is the benefit of versioning a REST api by date as Twilio does? - Code Utility - Code Utility
Pingback: How to Build a Java RESTful API with Spring Boot - FavTuts