1. Preface

Software iteration is a problem that developers must face, and one issue that is easily overlooked these days is API version control. Not all users are keen on the latest version of software, and business is fluid. So when a new version is released to ensure backward compatibility, API version control is needed. Today we will discuss the common Restful API version control.

2. API Version Control

Restful API version control is closely related to the business, but currently many average level product managers do not consider this, without a smooth transition will easily cause business turbulence, affecting the brand image and user experience.

Master version consistency strategy

When business changes are destructive to previous clients and incompatible, we should release this business release as a major version (Major), or else release it as a minor version (Minor).

restfull api version

The client should verify the consistency of its own master version number (1 in the above diagram) with the server’s master version, and can ask the user to upgrade when it does not match. This kind of control is the simplest and most hardcore. But not all scenarios are suitable for this approach, sometimes we need to support multiple versions of the client in parallel.

Multi-version parallelism

Multi-version parallelism all require the client to carry the version identifier in the request, which is usually done in the following ways.

Marking the version in the URI

Fatty mostly uses this approach in tutorials of previous articles, adding /api/v1 before all URIs, where 1 is the version number, which is iterable.

Marking versions in Host

You can also specify the version by Host, such as https://v1.myapi.com, https://v2.myapi.com point to different versions respectively, this kind of use is also more currently.

Declare the version in the Header

The above two will bring the version number explosion, so try to use it in major revision. To ensure the consistency of the API, you can also set the version number in the request header, e.g.

1
2
3
4
5
6
7
8
9
POST /foo/upload HTTP/1.1
Host: localhost:8080
Api-Version: v1
Content-Type: application/json

{
    "name": "felord",
    "age": 18
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
POST /foo/upload HTTP/1.1
Host: localhost:8080
Api-Version: v2
Content-Type: application/json

{
    "name": "felord",
    "age": 18
    "gender" 1
}

We identify the API version we expect to request by adding Api-Version to the Header.

3. How to route

Routing in the case of multiple versions is a problem, which needs to be talked about in conjunction with the way the application is deployed. If it is a single application with multiple versions, we need to write filters and interceptors for routing, here the URI approach is an exception, the minimum granularity of the version control of the URI is already the interface. This approach is generally used for small and medium-sized projects more.

If you are running v1 version on server A and v2 version on server B, you need to resort to gateways, proxies for routing, no matter where your version number is declared. As an example, the request header carries the version number and is routed by Nginx.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
upstream v1 {
    server 127.0.0.1:8081;
}
upstream v2 {
    server 127.0.0.1:8082;
}

server {  
    listen 8080;
    server_name localhost;
    charset utf-8;
    location / {
        set $not_match 0;
         # 根据 Api-Version 来进行路由
        if ($http_app_version = "v1") {
            proxy_pass http://v1;
            set $not_match 1;
        }

        if ($http_app_version = "v2") {
            proxy_pass http://v2;
            set $not_match 1;
        }

        if($not_match = 0){
            # 处理无匹配的问题   
        }
    }  
} 

Host, URI can be similarly routed for distribution.

By here you can also consider how a simple canary distribution can be done.

Reference https://felord.cn/api-version.html