Types of API versioning: How to decide on next API version strategy
Tags: rest, api, restapi, tutorial
Published: 2022-01-30 21:33:35

API versioning is the most debatable and inconclusive topic on the internet. There are various opinions, but after reading many blogs I wanted to put it straightforwardly, that is easy to understand and hopefully in a persuasive way.

## Introduction

Versioning of an API is inevitable as the software evolves. No one can get everything right in the first version itself, and ideally, we should not try to get everything and should follow the **YAGNI** principle (You Aren't Gonna Need It).
However, when you are an API provider, and consumers have started consuming API, it's quite cumbersome and difficult to roll out a new version or change without impacting the existing consumer. 

But, even before you decide that you really want to create a new version of the API, just hold that thought for a few minutes and ask the important question.

## Important question

### Why do you want to create a new API version?

This is the first question you should ask yourself, and the answer should fall in one of the three buckets.

### 1. Format Versioning
Every developer wishes that they could have named the entity a little bit differently. E.g. format versioning

```JSON
{
"Honda" : "Accord"
}


{
"Make" : "Honda"
"Model" : Accord"
}
```
So basically response data is the same but represented in a different format.

### 2. Entity Versioning
To explain the entity, let's take an example of FAQ (Frequently Asked Question) of different product types. Let's say you have product A and its FAQs, and after the launch of new product B, you want to have new sets of FAQs, but just for customers of the new product. So now you FaqAPI needs a new version where the response will be different for new customers.

### 3. Add New Entity
If you're going to create a new version of the API because you wanted to add the new entity in the API response? **then don't create a new version**. You should simply add the new entity in the response in a backward-compatible manner and existing consumers will ignore the new entity, as either, they don't know it or don't need it. API versioning is an expensive effort to perform (development, maintenance, and testing of API versions incur a cost), so better to avoid it. The [argument](https://www.infoq.com/articles/roy-fielding-on-versioning) by **Roy Fielding, the creator of REST**.

## How to achieve API versioning? (API Versioning Types)

### 1. URL
In my experience, I have seen this type of API versioning used in a lot of applications. Though it's easier to implement, it brings a lot of code maintenance overhead along with it.

In this type, you add the version in the URI path, e.g.

```
//most widely used 
https://www.awesomeapi.com/api/v2/product

OR

https://www.awesomeapi.com/api/2/product
```

### 2. Query Parameter
You can also create a new version by adding query param in the URL, as below

```
https://www.awesomeapi.com/api/product?ver=2
```
Once again an easy choice, but this is going to make the code bloated and more complex. As probably you're going to put more conditions in the same method to decide whether to choose version 1 Vs version 2.

### 3. Custom HTTP Request Header
The third way is to add a custom HTTP request header in the API request as below

```
HTTP GET:
https://www.awesomeapi.com/api/product
Accept-Version: 2
```

This is quite an elegant way to do it, but I'm more inclined towards the fourth way.

### 4. Existing HTTP Request Header (Content Negotiation)
This is similar to the third type, however, here instead of creating a new custom header, you're going to pass the version information in the Accept header.

```
HTTP GET:
https://www.awesomeapi.com/api/product
Accept: application/vnd.awesomeapi.v2+json
``` 

Though, to access a particular version API (HTTP GET method), I won't be able to just copy and paste the URL in the browser, however, tools like postman, curl are handy, using which it's easy to add the header in the request.

## Most Difficult Answer
Now the question is which one is best or worst? I feel not everything can be categorized as wrong or right. Having said that, I feel API versioning via content negotiation (existing Accept HTTP header) is the most preferable way to do it.

### So Why Accept Header?
When the consumer is consuming your API, they have put a lot of effort into implementing changes per the API contract that you provided at the beginning and you probably don't want to break their code. 

Per [Roy Fielding's untangled article](https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven).

> A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience.

So clearly, URL is not part of the API contract, hence type 1 & 2 shouldn't be used for API versioning, as both are URL-driven mechanisms.

Now, how about HTTP header or Media Types? Again in the same untangled article Roy Fielding states that

> A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types.

So clearly Media type is a part of API contract, and an ideal technique to be used in API versioning. 
But now the question comes to mind, **should we use a custom header or an already existing header?** HTTP header is semantic of the HTTP spec and just as the semantics of request verbs make a lot of sense, so is the HTTP Media types. So I'm more in favor of using the existing header. Hence, the fourth type of API versioning is the most preferable.

Having said that, HTTP caching is a major concern when it comes to API versioning. So URL caching is easier, but too many URL versions create load on the cache server, whereas on the other hand, caching based upon Media Type is a little complex.
So you would have understood why API versioning is so debatable and inconclusive topic, and discussion can go all day long 😂.

But, in the end, all API versioning types come with their pros and cons, it ultimately depends upon the API and situation. Hence, there is no **Silver Bullet** in the API versioning case and the decision should be taken based upon facts that which type is most applicable in your API case.

_If you have reached here, then I did a satisfactory effort to keep you reading. Please be kind to leave any comments or ask for any corrections. **Happy Learning!**_

## Reference Links
1. https://cloud.google.com/blog/products/api-management/api-design-which-version-of-versioning-is-right-for-you
2. https://www.infoq.com/articles/roy-fielding-on-versioning/
3. https://www.troyhunt.com/your-api-versioning-is-wrong-which-is/
4. https://www.baeldung.com/rest-versioning
5. https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

## My other blogs:
- [Log4J zero-day vulnerability demystified - Log4Shell](https://dev.to/akdevcraft/log4j-zero-day-vulnerability-demystified-log4shell-1f0h)
- [Private Cloud Vs Public Cloud Computing](https://dev.to/akdevcraft/private-vs-public-cloud-computing-5b74)
- [Containers Vs Virtual Machines, which is better and why?](https://dev.to/akdevcraft/containers-vs-virtual-machines-45m1)
- [Why we need multiple code analysis tools?](https://dev.to/akdevcraft/why-we-need-multiple-code-analysis-tools-3d9o)