In this article of REST with Spring Series, we will discuss versioning a REST API.
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
URI design is the most prominent part of a REST API and, therefore, a potentially long-term commitment towards the users of that 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
As a thumb rule, a big number change(e.g. v1 to v2) shows groundbreaking changes or significant milestone in the REST API design and features. This also shows 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.
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.
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 a new version to our REST API resource structure
https://hostname/v2/products
https://hostname/v2/customers
The version need not be numeric. Let’s look at some pros and cons of this approach.
Pros:
Cons:
Content negotiation using HTTP Accept header can be used for the REST API versioning. To handle versioning, REST API would use 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 it define 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 look at some pros and cons of this approach.
Pros:
Cons:
Another alternative is to use a custom header for handling API versioning. This approach is like the one described in section 2.2.
Accept-version: v1
Accept-version: v2
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
The idea of versioning with a RESTful API is far from reaching a universal standard. As a thumb rule, we can follow certain guidelines while versioning our REST API.
http://www.javadevjournal.com/v3.0/products/228781
http://www.javadevjournal.com/v3/products/228781
should be aliases
Recommendation is to not use API versions in resource URIs, however, using a version number in the URL should be not a bad practice when the underlying implementation changes and being used by all major players (e.g. Google, GitHub etc.)
We discussed when we need API Versioning in Section 1, let’s take examples to understand it more clearly.
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.
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 and 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"
}
}
The idea of versioning with a RESTful API is 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.
Hello!! Welcome to the Java Development Journal. We love to share our knowledge with our readers and love to build a thriving community.
Leave a Reply