How are REST APIs versioned?

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
Twitter 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
Facebook 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/
LinkedIn 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
Reddit 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

35 thoughts on “How are REST APIs versioned?

  1. Pingback: How are REST APIs versioned? | Lexical Scope | nodeJS and Web APIs | Scoop.it

  2. Pingback: How are REST APIs versioned? | Lexical Scope | Modern web development | Scoop.it

  3. Pingback: How are REST APIs versioned?

  4. Pingback: REST Fundamentals | planetgeek.ch

  5. 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.

      • 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.

  6. Pingback: Revealing KijiREST: Resources | Kiji Community - Build Real-Time Scalable Data Applications on Apache HBase

  7. 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

  8. Pingback: REST Fundamentals | bbv Blog

  9. 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

    • 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.

  10. Pingback: Decoupling API Versions From Codebase Versions | Haddad's Journal

  11. 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.

  12. Pingback: El mekki anouar | API Versioning – Different Approaches to API Versioning (1)

  13. Pingback: RESTful APIs | LibreNMS development blog

  14. Pingback: Designer une API REST | OCTO talks !

  15. Pingback: Make Breaking Changes without API Versioning | zhengziying.com

  16. Pingback: REST y el versionado de servicios | Adictos al Trabajo

  17. Pingback: Shaun Abram » Blog Archive » Versioning APIs

  18. Pingback: REST API Versioning | onehundred15

  19. Pingback: How to design a REST API | OCTO talks !

  20. Pingback: API versioning methods, a brief reference

  21. Pingback: Working with Microservices in an Ideal World - WanariLeaks

  22. Pingback: על המגבלות של REST – בשירות מערכות ווב בנות-זמננו – בלוג ארכיטקטורת תוכנה

  23. Pingback: Web API 版本控制的几种方式 - 算法网

  24. Pingback: What is the benefit of versioning a REST api by date as Twilio does? - Code Utility - Code Utility

  25. Pingback: How to Build a Java RESTful API with Spring Boot - FavTuts

Leave a Reply to abhishekCancel reply