Buy @ Amazon

Versioning Approaches for RESTful APIs

When you develop your application for consumption by other applications, you do so by exposing your application's endpoints. This endpoint could emit XML or JSON data depending on whether SOAP or REST protocol is supported. As reality would have it, the domain keeps evolving keeping up with the demands of the consumer applications and the challenge is not all consumer applications want the same kind/structure of data or that they aren't keeping up with the pace of your evolution. So that brings the need for versioning your API endpoints, to meet the backward compatibility of at least some of your consumer applications. This leaves us with the question, as to how do we do versioning of our endpoints? And this post is about versioning the REST endpoints. 

There are 4 below ways in which you can version your REST APIs:

  • Option 1: URI Versioning
    https://mydomain.in/api/{api_version}/myresource
    https://mydomain.in/myTargetResource/myTargetService/{api_version}/
    https://api.plivo.com/v1/myresource
    https://api.twilio.com/api/2020.06.01/myresource
    https://instance_name.salesforce.com/services/data/v49.0/
  • Option 2: URL Query Request Parameter Versioning
    https://mydomain.in/api/myresource?version=1.0.0
  • Option 3: Custom Request Header Versioning
    https://mydomain.in/api/myresource
      headers[X-API-VERSION=1.0.0]
    https://mydomain.in/api/myresource
      headers[Api-Version=1.0.0]
    https://mydomain.in/api/myresource
      headers[MyCustomHeader=1.0.0] where,
    • Any headers beginning with X- are custom headers, and are not included in the HTTP spec..
    • There are a few interesting bits in the response headers. As expected, the Content-Type is application/json.
  • Option 4: Media Type Request Header Versioning
    https://mydomain.in/api/myresource
      headers[Accept: application/vnd.vendorprefix-v1.0.0+json]
    https://mydomain.in/api/myresource
      headers[Accept: application/vnd.mycompany+json;version=1.0.0]
    where,
    • Accept header in http advertises which content types, expressed as MIME types, the client is able to understand. Using content negotiation, the server then selects one of the proposals, uses it and informs the client of its choice with the Content-Type response header.
    • The vendor prefix (vnd.) indicates that it is custom for this vendor.
    • The +json indicates that it can be parsed as JSON, but the media type (defined by Content-Type header) should define further semantics on top of JSON.

There is no one approach that is always better than the others listed above. What works for you, depends on your context and in part is also, likely a subjective decision. That said there a few things to take into consideration during your discussions with your team and they are the following questions that can help you find your deciding factor:
  • Do you (or your consumer applications) see versions in URL as noise polluting it? If so, you can rule out options 1 and 2 in the list above.
  • Do you (or your consumer applications) see versions in custom Headers as noise polluting it? If so, you can rule out option 3 and potentially even option 4, if you are too finicky about it.
  • Which approach is the easiest to implement? An answer to this depends a lot on your choice of framework and architecture. Does your choice of framework support routing for sophisticated URL Versioning? 
  • How does it affect caching? For instance, header based versioning (options 3 and 4) affects URL based caching, because all the versions share same URL; you will have to change your caching strategy to accommodate request headers in them.
  • Do you document your API for publishing? What is its implication on the choice of tool for documentation to accommodate versioning strategy to how it gets published.

Different companies has taken different routes to REST API Versioning. Here are some examples of companies for each of the versioning strategy.

Additional Resources