REST API Versioning Approaches

Kenny Wang
HMH Engineering
Published in
4 min readNov 14, 2019

Change in an API is inevitable as your knowledge and experience of a system improve. Managing the impact of this change can be quite a challenge when it threatens to break existing client integration.

REST doesn’t provide for any specific versioning guidelines but the more commonly used approaches. Here we list the commonly used approaches and the pros and cons.

Common Versioning Approaches

Versioning through URI

Version is very explicitly defined as part of the API URIs, an example below

https://{dns_name}/{domain_name}/{version}/{resources}...dns_name could be api.abc.com for external facing APIs or prod.abc.internal for internal APIs, domain_name could be reading-inventory.version could be v1, v2, so on.A concrete example would be https://api.abc.com/reading-inventory/v1/quizzs/...

And the backend SpringBoot controller could have code to handle this

@GetMapping({"/v1/quizzes"})
public List<Quiz> getAllQuizzes() {
...
}

The REST API purist would argue that API URI is used to identify a resource, while version is an attribute of the resource. In practice, the resource is identified by the uri after versioning tag.

Versioning through Query Parameter

This approach makes versioning as part of the request parameter, either make one as required query parameter or provide a default version to catch all if this is an optional parameter. An example below

https://api.abc.com/reading-inventory/quizzs?version=v1

And the backend SpringBoot controller could have code to handle this

@GetMapping({"/quizzes"})
public List<Quiz> getAllQuizzes(@RequestParam("version") String version) {
// logic here to check the passed in version string and based on
// that process the request differently
...
}

This approach is highly used by Amazon, Google and Netflix.

Versioning through Accept Header

This approach requires the API clients to provide the version information through the Accept (request) header along with the content-type (media) in the response — it is the preferred way, as this helps to version APIs without any impact on the URI. An example below

Accept=application/quizzes-v1+json
https://api.abc.com/reading-inventory/quizzs // URI contains no version info

As part of response, it should contain the version info in Content-Type header field, something like this

Content-Type=application/quizzes-v1+json;charset=UTF-8

Versioning through Custom Header

This approach defines a new header that contains the version number in the request as part of request header itself. A custom header allows the client to maintain the same URIs, regardless of any version upgrades. This approach is similar to the previous. The customer header name could be any name. An example below

x-api-version=v1
https://api.abc.com/reading-inventory/quizzs // URI contains no version info

And the backend SpringBoot controller could have code to handle this

@GetMapping("/quizzesByCustomHeader")
public List<Quiz> getAllQuizzes(@RequestHeader("x-api-version") String version) {
// logic here to check the passed in version string and based on
// that process the request differently
...
}

The response should contain the version info in a custom header field, for example,

x-api-version=v1

Versioning via Redirect

This approach basically use HTTP code 301 to redirect the client to a different URI to make further request. HTTP code 301 in the response indicates to the client that the URI has been permanently removed and the new URI is in the response’s Location header. An example below

GET https://api.abc.com/reading-inventory/quizzes

Would get the following response

HTTP status code 301
Location=https://api.abc.com/reading-inventory/v2/quizzes

Upon receiving this, client understands the semantics by extracting the new URI from the Location header, turns around and issue the following

GET https://api.abc.com/reading-inventory/v2/quizzes

Comparisons

Currently there is no “Best Solution for Restful API Versioning”, pros and cons [1–3], as demonstrated by the infographic below,

Summary

It’s clear that every versioning approach mentioned above have its pros and cons. When you pick a specific versioning approach, think about what you have done so far, and what’s the best to meet your business need and have least development effort.

With that, we outline some of the versioning best practices below,

Versioning Best Practices

  1. Using a new version when the current implementation breaks the existing clients.
  2. Once backwards compatibility is broken, or dramatically changing what’s in place, it’s time to consider another version
  3. Recommend to support 3 versions, so if the current API version is v4, only v2, and v3 will be supported while v1 will no longer be supported. No need to introduce minor versions.

Reference

  1. https://www.mnot.net/blog/2012/12/04/api-evolution
  2. https://restfulapi.net/versioning/
  3. https://www.baeldung.com/rest-versioning

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Published in HMH Engineering

HMH Engineering builds fantastic software to meet the challenges facing teachers and learners. We enable and support a wide range of next-generation learning experiences, designing and building apps and services used daily by millions of students and educators across the USA.