vlambda博客
学习文章列表

Nginx居然还能实现Restful接口的版本控制,涨知识了!


1. 前言

软件迭代是开发者必须面临的问题,现在有一个容易被大家忽略的问题就是 API 的版本控制。不是所有的用户都热衷于最新的版本的软件,而业务又是多变的。因此当新版本发布时要确保向后兼容,所以就需要 API 的版本控制。今天就来探讨一下常用的 Restful API 版本控制。

2. API 版本控制

Restful API 版本控制与业务息息相关,但是目前很多水平一般的产品经理不会考虑这些,没有平稳的过度就容易造成业务动荡,影响品牌形象和用户体验。

主版本一致性策略

当业务变动对以往的客户端造成破坏性,无法兼容时,我们应该将此次业务的发布版本作为一个主版本(Major)来发布,否则以一个次要版本(Minor)来发布。

版本示意图

客户端应该检验自身主版本号(上图中的 1)与服务端主版本的一致性,当不一致时可要求用户升级。这种控制是最简单、最硬核的。但是不是所有的场景都适合这种方式,有时候我们需要支持多版本的客户端并行的情况。

多版本并行

多版本并行都要求客户端在请求时携带版本标识,通常有以下几种做法。

在 URI 中标记版本

胖哥在以往文章的教程中多用这种方式,在所有的 URI 前增加/api/v1,其中1就是版本号,是可迭代的。

在 Host 中标记版本

你也可以通过 Host 来指定版本,如 https://v1.myapi.comhttps://v2.myapi.com分别指向了不同的版本,这种使用的也是目前比较多的。

在 Header 中声明版本

上面两种会带来版本号爆炸的情况,所以尽量在重大改版中使用。为了保证 API 的一致性,也可以在请求头中设置版本号,例如:

POST /foo/upload HTTP/1.1
Host: localhost:8080
Api-Version: v1
Content-Type: application/json

{
"name": "felord",
"age": 18
}
POST /foo/upload HTTP/1.1
Host: localhost:8080
Api-Version: v2
Content-Type: application/json

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

我们通过在 Header 中添加Api-Version来标识我们期望请求的 API 版本。

3. 如何路由

多版本的情况下路由就是一个问题,这就需要结合应用的部署方式来谈,如果是单应用多版本,需要我们编写过滤器,拦截器来进行路由,这里 URI 方式是一个例外,URI 的版本控制的最小粒度已经是接口了。这种方式一般用于中小型项目比较多。

如果你是在 A 服务器跑v1版本,B 服务器跑v2版本,就需要借助于网关、代理来进行路由了,无论你版本号声明在哪里。以请求头携带版本号由 Nginx 路由为例:

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 也可以进行类似的路由分发。

推荐阅读




欢迎关注,点个在看