Versioning a REST API

In this article of REST with Spring Series, we will discuss versioning a REST API.

 

Introduction

Evolving a REST API is a difficult and complex task. When REST API reached a point where it’s difficult to expand beyond the original intent, it’s time to consider the next version. In this post, we will walk through the different options of versioning a REST API. While going to next iteration for your REST API, we should consider following points

  • Is the next version/ iteration will be a whole number (e.g v1 to v2) or an increment to existing iteration (e.g v1.1 from v1.0).

URI design is the most prominent part of a REST API and, therefore, a potentially long-term commitment towards the users of that API.

 

1. When to Version REST API

As mentioned above, REST API design is a long-term commitment towards the users of that API, REST API should only be up-versioned when significant or groundbreaking changes made in the API. Here is the list of some common points when we

  • Remove API part.
  • Architectural changes to the API design.
  • Changes in the response format.

As a thumb rule, big number change(e.g v1 to v2) indicates groundbreaking changes or significant milestone in the REST API design and features. This also indicates REST API consumer significant changes. All minor changes like new endpoints etc. are known as non-breaking changes. Use minor version increment (v1.0 to v1.1) to show these changes in the API.

 

2. REST API Versioning Options

On a high level, there are 4 possible options when versioning a REST API. We are covering all these options with their pros and cons.

 

2.1 URI Versioning

This is the most commonly used and straightforward approach while versioning a REST API. Let’s take an example of following resources – products and customers.

https://hostname/v1/products
https://hostname/v1/customers

Let’s assume that we are introducing groundbreaking changes to the REST API,to represent this, we introduce new version to our REST API resource structure

https://hostname/v2/products
https://hostname/v2/customers

The version need not be numeric. Let’s take a look at some of the pros and cons of this approach.

Pros:

  • Enable version discovery.
  • Readability and dev friendly.
  • Ability to version specific resource branches.

Cons:

  • Violate the principle that a URI should refer to a unique resource or structure only.
  • New version breaks existing hyperlinks.
  • HTTP Caching is also a major concern.
  • New versions change resource name and location.

 

2.2 Versioning using Accept Header

Content negotiation using HTTP Accept header can be used for the REST API versioning. To handle versioning, REST API would make use of MIME type to determine the API versioning.

Accept: application/vnd.javadevjournal.v2+json
Accept: application/vnd.javadevjournal+json;version=1.0

it is important to understand here is that the client makes no assumptions about the structure of the response beyond what is defined in the media type.

############## GET Request for Products ##############
GET /products/228781 HTTP/1.1
Accept: application/vnd.javadevjournal.v1+json

############## Response ##############
HTTP/1.1 200 OK
Content-Type: application/vnd.javadevjournal.v1+json
{
    "product": {
        "code": "228781",
        "name": "Running shoes",
        "description": "one of the best running shoes"
    }
}

Let’s take a look at some of the pros and cons of this approach.

Pros:

  • Clean URI structure (no version information in the URI structure)

Cons:

  • Complex API structure since underlying system is responsible for figuring out which version of a resource to send.
  • Not enough semantic information. Information is not clear and hidden with use of Accept header.
  • Accept headers are hard to test.

 

2.3 Versioning using Custom Header.

Another alternative is to use a custom header for handling API versioning. This approach is similar to the one described in section 2.2.

Accept-version: v1
Accept-version: v2

 

2.4 Versioning using URI parameter.

This is the least used method to version your REST API. Append version as a query parameter.

http://host/shopping?version=2.0
http://host/catalog/titles/series/70023522?v=1.5

 

3. REST API Versioning Best Practices

The idea of versioning with a RESTful API is certainly far from reaching a universal standard. As a thumb rule, we can follow certain guidelines while versioning our REST API.

  • REST API versioning is dependent upon the REST API design. With good API design, major versions are rarely needed except when changing the behavior of the whole API at once.
  • The URI design should have less natural constraints and it should be preserved over time.
  • Use aliasing while versioning your REST API. For example
    https://javadevjournal.com/v3.0/products/228781
    https://javadevjournal.com/v3/products/228781

    should be aliases

  • If REST API client tries to use old API, the system should return HTTP 410 status code.

Recommendation is to not use API versions in resource URIs, however, using a version number in the URL should is not a bad practice when the underlying implementation changes and being used by all major players (e.g. Google, GitHub etc.)

 

4. Examples

We discussed when we need API Versioning in section 1, let’s take some examples to understand it more clearly.

 

4.1 Adding Additional information to Resource

the Resource representation in REST API should not be tightly bound to a client and should be as generic as possible. The client should only consume require information and ignore information which is relevant to the client. This help to expand REST API resource representation without breaking existing clients. Let’s take an example of product resource.

{  
   "product":{  
      "code":"228781",
      "name":"Running shoes",
      "description":"one of the best running shoes",
      "price":"100.00"
   }
}

Let’s assume that we may want to introduce “promotional price” as an additional information in the REST response needed by some REST client

{  
   "product":{  
      "code":"228781",
      "name":"Running shoes",
      "description":"one of the best running shoes",
      "price":"100.00",
      "promotional_price":"90.00"
   }
}

This change will not break existing clients, they can continue to ignore “promotional_price” information.

 

4.2 Changing Existing Representation/Semantic Changes

Redesigning, changing or removing the representation is known as breaking changes and require REST client to change the implementation. To handle such changes, we have the options to use HTTP header as part of the content negotiation or use API versioning if API includes major changes (content as well as semantics). Let’s take an example where we like to change the product code to product SKU in the API

############## GET Request for Products ##############
GET /products/228781 HTTP/1.1
Accept: application/vnd.javadevjournal.v2+json

############## Response ##############
HTTP/1.1 200 OK
Content-Type: application/vnd.javadevjournal.v2+json
{
    "product": {
        "sku": "228781",
        "name": "Running shoes",
        "description": "one of the best running shoes",
        "price" : "100.00",
        "promotional_price":"90.00"
    }
}

 

Summary

The idea of versioning with a RESTful API is certainly far from reaching a universal standard. In this article, we tried to cover a complex topic of versioning a REST API. We discussed 4 different approaches to consider while versioning the REST API. Take in to account your development team and customers while determining the best approach for versioning.

 

Additional Readings

Umesh

Hello!! I am Umesh- an engineer by profession and a photographer by passion.I like to build stuff on the web using OSS and love to capture the world through my lens.

follow me on:

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of