Web Api Versioning

Keep your web service stable by versioning

Adem Catamak
4 min readDec 1, 2021

Yazının Türkçe versiyonuna bu link aracılığıyla ulaşabilirsiniz.

If you have developed a long-term project in accordance with the server — client architecture, you have encountered requests that will cause you to lose backwards compatibility at some point. In such cases, the easiest and the most practical solution to develop without breaking the existing system is to make versioning.

Through versioning, we can have endpoints in our system that can exist at the same which receive requests, create responses or execute transactions in different ways. After preparing a new version, we can allow time for the clients to switch from the old version to the new version, after the specified period, we can remove the old version from the system and complete the development process without causing any issues to the end user.

Note: You can access the sample project developed with .Net 5 on GitHub.

Photo by Matt Hoffman on Unsplash

Let’s say we create an order record by taking user information, product code, product quantity and address information. Our schematic will be as follows.

[POST] http://base-url/orders
{
"userId" : "dummy-user-id",
"productCode" : "computer-123",
"quantity" : 3,
"address" : "some dummy address"
}

Let’s imagine that; in order to speed up the shipment process an improvement should be made regarding the systematic retrieval of address information. In this situation, country and city information must be obtained from separate fields. Let’s assume that the schema of the request that will be formed as a result of the new structure you will develop will be as follows.

[POST] http://base-url/orders
{
"userId" : "dummy-user-id",
"productCode" : "computer-123",
"quantity" : 3,
"country": 90,
"city" : 34,
"addressDetail" : "some dummy address detail"
}

Now, considering our example scenario, let’s take a look at they ways that we can do versioning.

Versioning with URI

In this method, we demand that the client sends the version information that is desired to be used in the URI.

[POST] http://base-url/v1/orders
{
"userId" : "dummy-user-id",
"productCode" : "computer-123",
"quantity" : 3,
"address" : "some dummy address"
}
[POST] http://base-url/v2/orders
{
"userId" : "dummy-user-id",
"productCode" : "computer-123",
"quantity" : 3,
"country": 90,
"city" : 34,
"addressDetail" : "some dummy address detail"
}

Advantages:
- It is easy to use.
- The status of versioning is easily recognizable by the client.
- Since the versioning information is on the URI, caching by the client can be done on a version basis.

Disadvantages:
- Does not comply with REST rules.
- When the versioning value changes, it affects the whole resource. For this reason, we cannot change the version for a single service point. For example, while we want to make a version change for the POST service endpoint, we have to prepare new versions for operations such as GET, PUT, PATCH, if any, on the “order” resource.

Versioning with Query-Parameters

In this method, we demand that the client sends the version information that is desired to be used as a query-parameter. In this way, we will know the schema of our request object.

[POST] http://base-url/orders?v=1
{
"userId" : "dummy-user-id",
"productCode" : "computer-123",
"quantity" : 3,
"address" : "some dummy address"
}
[POST] http://base-url/orders?v=2
{
"userId" : "dummy-user-id",
"productCode" : "computer-123",
"quantity" : 3,
"country": 90,
"city" : 34,
"addressDetail" : "some dummy address detail"
}

Advantages:
- Setting the default version value is much easier.
- Versioning is possible per endpoint.

Disadvantages:
- If it is combined with versioning via URI, it is very difficult to do version management.
- Parameters must be checked to determine the version value.

Versioning with Header

In this method, we demand that the client sends the version information that is desired to be used via the request header.

x-api-version: 1
[POST] http://base-url/orders
{
"userId" : "dummy-user-id",
"productCode" : "computer-123",
"quantity" : 3,
"address" : "some dummy address"
}
x-api-version: 2
[POST] http://base-url/orders
{
"userId" : "dummy-user-id",
"productCode" : "computer-123",
"quantity" : 3,
"country": 90,
"city" : 34,
"addressDetail" : "some dummy address detail"
}

Advantages:
- It offers a granular structure. Versioning per endpoint is quite easy.
- There is no difference in URL structure between different versions. It is more in line with REST rules.

Disadvantages:
- Not as visible as URI or Query-Parameter methods.
- It is difficult to repeat the request through the browser. For example, in the scenario where your version information is on the URI or Query-Parameter, when you copy the URL value and send a request from your browser, the version value will also be transmitted, therefore, you will be submitting your request correctly. With this way of versioning (using the header), however, since you cannot transmit the version information, the way the request is processed may not be what you expect. You will have to use client applications such as Postman to transmit your request with version value.

I have mentioned the basic 3 methods used during web service versioning. I hope it was a useful article. You can click this link to check out my other articles.

--

--