Thursday, June 6, 2024

How to version REST API? URL vs Header Versioning? Example Tutorial

Designing a real world, industry standard RESTful API can be a tricky challenge becuase there is no real standard exists. To add into that, there is also a lot of confusing topics e.g. PUT vs POST for creating and updating resources, or using URL or Header for versioning. There are a lot of advices you will find on internet often confusing and advocating one or other alternative, but it ultimately depends upon your own wisdom and use cases to come up with elegant RESTful URIs, which supports both filtering and versioning. There are both pros and cons of URL versioning and Hypermedia version, which we'll discuss in this article, but the most important lesson to learn is that you should always version your REST API

Versioning a REST API helps you to develop faster and prevents invalid requests from hitting updated endpoints. It also helps on major API version upgrade as you can continue to offer old API version for a short period of time. 

When it comes to REST API versioning , there are two main approaches, one advocate putting version on URI and second suggest putting versions in header, we will see both of them and also find out the pros and cons of each approach. 

Here is a quick overview of both of them using a diagram from ByteByteGo :

REST API URL vs Header Versioning



What is URL versioning of REST API?

The URL way is classic way to version web API, it exists even before REST, when we used simple GET web services to access the web. In this type of API versioning you simply add a version number in the URL itself as shown below:

https://library.com/api/v1/book/12345

Now, if you come up with another version, you can change the URI as shown below:

https://library.com/api/v2/book/12345

You can also use major.minor version for your API as shown below:

https://library.com/api/v1.1/book/12345

It's also a good idea to have a URL without version which redirect to the latest version or behave identically like:
https://library.com/api/v2/book/12345, and https://library.com/api/book/12345 should return same result if v2 is the latest version

Tools like Swagger or Open API can also be really helpful on REST API Versioning and documentation and you can enable Swagger by just adding one JAR in your class path if you are using Spring Boot. 

Once you have done that just hit the https://localhost:8080/swagger-ui.html  (port can be different for your application). and it will open the swagger GUI which not only allow you to see the version but also all the REST API exposed by your application. 

You can also play with them by calling them using Swagger GUI. It even allow you to call the POST method and send JSON payload without any external tool like Postman or Curl

Here is how Swagger UI looks like:


Coming back to versioning, you can also use HTTP status codes for URL based API versioning e.g. 301 (Moved Permanently) and 302 (found).  

The 301 Moved permanently response code indicates that the resource with a requested URI is moved permanently to another URI (which should be a resource instance permalink that does not contain API version info). 

This status code can be used to indicate an obsolete/unsupported API version, informing API client that a versioned resource URI been replaced by a resource permalink.

On the other hand, the 302 Found status code indicates that the requested resource temporarily is located at another location, while requested URI may still supported. 

This status code may be useful when the version-less URIs are temporarily unavailable and that a request should be repeated using the redirection address (e.g. pointing to the URI with API version embedded) and we want to tell clients to keep using it (i.e. the permalinks).

Here is a nice diagram which suggest how you can use major version, minor version and patch version effectively with REST API:




What is Header based Versioning of REST API?

This is another way to version your REST API. In this type of API versioning, the version is provided in the header instead of URL as shown below:

GET /api/v1/book/12345 HTTP/1.1
Accept: application/vnd.api.article+xml; version=1.0

This is also known as Hypermedia way of versioning REST API. In order to test this kind of API, you will need a tool like Postman where you can set specific header, you cannot pass the version directly on the browser which is one advantage of using earlier approach where version is indicated in the URL itself. 



Which one to use? URL vs Header versioning?

The world is divided on whether an API version should be included in the URL or in a header. Theoretically, it should probably be in the header but practically I like the URL based API versioning because it provides browser explorability across versions.

It's also more visible and easy to sync up directories.

There is also a midway exists, where some companies e.g. Stripe uses both URL and header based versioning to provide best of both world. 

In this type, the URL has a major version number (v1), but the API has date based sub-versions which can be chosen using a custom HTTP request header. 

In this case, the major version provides identity to the API as a whole while the sub-versions accounts for smaller changes field deprecations, endpoint changes, etc.

Here is a nice comparison of  Header versioning of REST PAI vs URL versioning from ByteByteGo, my favorite portal for learning System design

Which one to use? URL vs Header versioning?



That's all about different types of API versioning in REST. An API is never going to be completely stable. Change is inevitable. What's important is how that change is managed. Well documented and announced multi-month deprecation schedules can be an acceptable practice for many APIs. It comes down to what is reasonable given the industry and possible consumers of the API.

 Other RESTful Web Services articles you may like to explore
  • Restlet HelloWorld Example in Java and Eclipse (tutorial)
  • Difference between POST and PUT? (answer)
  • Top 10 Java Web service interview questions (see here)
  • Difference between GraphQL and REST? (graphql vs rest)
  • When to use the PUT vs POST method in REST? (answer)
  • How to send HTTP POST request from Linux? (curl example)
  • 3 ways to convert String to JSON Object in Java? (example)
  • How to set Accept Header using Spring Boot RestTemplate? (example)
  • 5 JSON parsing library Java and JEE developer should know (article)
  • How to call REST API from command line using curl and wget? (curl vs wget)
  • Difference  between SOAP and RESTful web service in Java? (see here)
  • Difference between @RequestParam and @PathVariable? (request param)
  • 15 REST Web Services framework Interview Question (see here)
  • 10 HTTP Status Code Developer Should Learn (http response code)
  • What are idempotent and safe methods of HTTP and REST? (answer)
  • Difference between gRPC, REST, SOAP and GraphQL? (gRPC vs REST)
  • Top 10 RESTful web services interview questions for Java developers (see)
  • How to create REST API using Jersey? (jersey example)
  • What is the purpose of different HTTP methods in REST? (answer)

Thanks you for reading this article. If you like please leave a comment or share with your friends, I will appreciate it.

1 comment :

Anonymous said...

Which method of REST API versioning do you recommend? URL or Headers?

Post a Comment