What is API versioning and why is it needed?

Maxim Danilov
4 min readOct 2, 2024

--

E-Dalle, API-versioning.

API documentation is the most important part in API development, because it is impossible to use any external API without it and nobody knows how to use your API without documentation.

The API documentation describes HOW the client should use the provider’s API, treating the service itself as a balckbox. And well documented API not require to inform about the service implementation.

Over time, you may encounter demands to improve, fix, or extend an existing API implementation. However, when a specific implementation changes, the interaction protocol changes too, for example, when authorization process for API access is changed or responce was changed accordinly the current GDPR. If API has external customers — such changes break the interaction with them. A broken API interaction, will lead to a reduction in the number of customers, and some investment will be required to restore the service. Of course, all of this has a negative impact on the reputation of the provider.

To solve the problem of API changes, we can use API versioning.

API versioning — mentioning the API version in the request, to clarify which protocol for interacting with the provider is expected by the client.

There are many different ways to mention the API version:

In parentheses is a reference to a well-known service that uses this approach.

1. Include the version in the URL. (x/twitter):

https://api.x.com/1.1/statuses/lookup.json
https://api.twitter.com/2/tweets

In my opinion it’s not really versioning: it’s just that different url’s provide different API’s, and should be followed by proper documentation. Clients using an old version continue to work when a new version is added. All url’s can be reflected in OpenAPI.yaml.

openapi: 3.2
info:
version: 2.0
servers:
- url: http://mydomain.com
paths:
/v2/service:

In the example, I don’t specify the version in info.servers.url, but I write the version in paths, because I want to generate a generic yaml of the whole project.

The advantage of this approach is the simplicity of development and testing. You work with each version as a separate simple service. The disadvantage is also obvious: the number of url’s grows, each version of the service is tested and deployed separately, etc. And, of course, to switch to a new version, external developers will need to make more customizations in case of controlling requests to external URL’s.

2. Adding the version in the GET parameters (Microsoft):

https://api.contoso.com/products/users?api-version=1.0

Based on my almost 30 years of experience in developing services, I would not recommend using versioning in GET-parameters.

In addition to other problems, mentioned below in versioning via headers, this method violates the Single Responsibility Principle: in GET parameters we usually provide internal parameters for configuring the current service, while in the case of versioning we transmit an “external” pointer to use another version of service.

While I don’t like this alternative, it has a solid advantage — the url doesn’t change depending on the API version. The second advantage is to achieve more stability of the service. The version is determined after the request is received, If it turns out that the version is incorrect, you can still provide a useful response instead of 404.

3. Passing the version via Headers (Zalando):

GET /service HTTP/1.1
Host:mydomain.com

• Using Accept:
Accept: application/example.api+json;version=2.1

• Using Content-Type
Content-Type: application/vnd.example.v2+json

• Using сustom-HEADER
X-API-Version: 1

Many articles can be found against this approach, but this versioning has one significant advantage: Adding new API versions does not require client-side changes.

In contrast, however, this versioning-approach cannot be clear reflected in the OpenAPI.yaml, and it is difficult to organize autodocumentation and autotesting.

Based only on the provided information, we can imagine that creating an additional URL, included a new version is always cheaper to develop than using versioning via headers/GET. However, the persistence of the URL with versioning over headers guarantees the stability of access to the service for all consumers.

Stability vs Cheaper development. What to choose?

The solution depends on the business needs. For example, Zalando has abandoned the URL versioning, Microsoft offers to use GET-parameter versioning, and most services use versioning in URL’s, like PayPal, x/Twitter etc.

But I suggest you think deeper and collect the benefits of all approaches: We can create an Api-Proxy service which allows versioning in headers/GET for external users. After defining the version service can send internal request to public or non-public APIs with URL versioning, that are easy to test and document. And this is important because simple testing or documentation can be fully automated with various AI-based API testing/documentation services. I like that possibility a lot!

Proxy API help you transform api requests vithout version in url.

Idea with additional Proxy-Service can be applied to both: new and existing projects. I mentioned the Proxy-API feature it in my talk “An alternative view on the OpenAPI documentation” at EUROPYTHON 2024, but I haven’t fully covered this topic.

Additional sources that I used in writing this article:

I am extremely grateful to Akshay Sethi from KushoAI, for the motivation to write this article.

--

--

Maxim Danilov
Maxim Danilov

Written by Maxim Danilov

Python & Django Developer and speaker

No responses yet