DEV Community

Cover image for Designing Versioning for your API
Anayo Samson Oleru
Anayo Samson Oleru

Posted on

Designing Versioning for your API

In this article, I am going to show you how to design versioning for your API. We will start by talking about why versioning is important for an API and then the strategies for versioning your API.

First question you want to ask yourself is: Do I really need to version my API? This is something very important to think about, because once you publish your API, and once client have written against the API or users have started relying on that API, it is set on stone, you won't want to make changes that would break your client and you won't want to be in a position where when there is a new API change, you are always thinking about how to make those changes without breaking the client.

But versioning can also be a overkill, if the API is only being used by your team. But if your API has internal or external customers, that has developers writing code using your API, that may not be just your small team then versioning your API is super important from the planning phase.

Your API requirements will always change, no matter what you do, no matter how much you designed it. And when this happens, your API will have to change. Again, another reason to consider and learn how to version your API.
The goal is to evolve your API without breaking existing client. What this doesn't mean is that, every time you release a product version that you're going to change your API. API versioning is different and harder than product versioning.The reason for this is that you need to support both old and new versions, side-by-side deployment of multiple versions, you will need an indication from clients about what version they want to use, and allow older code to make changes to allow them continue to use the API.
And so planning for and designing versioning upfront, will make maintenance of your API easier in longer term.

Ways to version your API

There are a lot of ways to version your API, with their own advantage and disadvantage. You should find the mechanism or way of doing version that makes the most sense to your organisation. And this is going to depend a bit on the requirements, remember you are serving your clients not yourself. Making versioning easy to use for your clients is way more important than making it way more easier on your development staff.

1. Versioning in the URI path
This is the commonly used API versioning.

https://anayooleru.com/api/v2/articles
Enter fullscreen mode Exit fullscreen mode

We can see in the example above that the 'v2' inside the path to my articles API is indicating the version of the API. The advantage of this, is that it makes it clear to the client which version they are using and where the version is handled. But the disadvantage, is that every time there is a version change, clients would have to change all the URIs and that can be a lot of repeated work.

2. Versioning with Query String

Another versioning strategy is the query string versioning.

https://anayooleru.com/api/articles?v=2.0
Enter fullscreen mode Exit fullscreen mode

In this case, like the example above we can add a query string that ask for a specific version of our API. The advantage of this is that we can have a default version that will always be used by our API when the version query string isn't supplied, and that can be the latest version or whatever default version we set. So it makes versioning optional. But the downside of this is clients can easily forget or missed that they need to set a version, what is the point of versioning if it isn't being used.

3. Versioning with Headers

GET /api/articles HTTP/1.1
Host: localhost:44388
Content-Type: application/json
X-Version: 2.0
Enter fullscreen mode Exit fullscreen mode

In the above example, the X-Version header is used to specify the version of an API to be used. This approach offers some advantages similar to using query strings, but it separates versioning from the rest of the API. Instead of requiring changes in the actual API code, only the interceptor in the API client needs to add this version header. This decoupling allows for easier maintenance and updates to the API, as well as providing flexibility in managing different API versions. However, implementing this approach may require a more experienced developer who understands how to add headers and intercept API calls to include the required headers in their client code.

4. Versioning with Accept Header

GET /api/camps HTTP/1.1
Host: localhost:44388
Content-Type: application/json
Accept: application/json;version=2.0
Enter fullscreen mode Exit fullscreen mode

In the example, the Accept header is used to specify the desired version of the API. By including the version information in the Accept header, the client can indicate the specific version it expects in the response. This approach allows the server to send back the content with the corresponding version information, ensuring proper versioning throughout the communication.

One advantage of using the Accept header for versioning is that it can provide a standardised way to handle versioning within the API. The Accept header is a well-known HTTP header that is widely supported. Additionally, it allows for flexibility in managing different versions of the API.

However, implementing versioning through the Accept header may require a more experienced developer who understands how to manipulate headers and handle the versioning logic in the client code. It can be more sophisticated compared to other versioning approaches, but it offers the benefit of keeping the version information within the communication flow.

5. Versioning with Content Type
This is the most complex type of versioning to use, and can be very useful:

GET /api/camps HTTP/1.1
Host: localhost:44388
Content-Type: application/vnd.yourapp.article.v1+json
Accept: application/vnd.yourapp.article.v1+json
Enter fullscreen mode Exit fullscreen mode

A custom Content type is used to indicate the specific version of the API being requested and the version expected in the response. This approach allows for granular versioning, where different parts of the application can be in different versions.

Using custom Content Types and Accept headers for versioning can be particularly useful for long-lived applications. It allows for tracking the version of the content received from the API, rather than just the version of the API itself. This is beneficial when dealing with scenarios where data might be retrieved at one point and updated at a later time. The content and accept headers associated with the stored data can help identify the specific version of the content.

However, it's important to note that implementing and maintaining this type of versioning can be more complex and requires a higher level of developer maturity. Handling different versions of the API and managing custom content types can involve additional complexities. Therefore, it is important to carefully consider the trade-offs and ensure that the benefits outweigh the added complexity for the specific use case.

What we have learned

1. Versioning is critical: For a mature, long lasting API, I have shown you that versioning your API is crucial at the very start of your design process.
2. Decide on the which versioning scheme will fit your requirements: I showed you some of the important versioning strategy out there. Find the one that fits best for both the team you have and along with the kind of customer requirements you have.
3. Content-Type versioning: One of the most complex versioning strategy but with long lasting API benefit.

Top comments (0)