NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

如何版本化你的 API?

  • 2017-09-11
  • 本文字数:1917 字

    阅读完需:约 6 分钟

如何版本化 API 需要考虑各种实际业务场景,但是一个完备的 API 应该是:

  • 和客户端交互的约定。API 需要确保稳定性,预先定义各种可能返回状态,包括各种异常。客户端无需考虑约定之外的情况。
  • 向下兼容。在 API 没有变化的时候,API 实现的更新和升级,都应该确保原有客户端请求不出现问题。
  • RESTful。API 设计应该能够遵照 RESTful 风格,通过 URI 来表示资源,通过 HTTP GET、POST、PUT、DELETE 等方法表示操作行为。

为了满足上述约定,版本化 API 不失为一种保持兼容性的好方法。版本化 API 的通常方式有:

URI 中设置版本

这种方式通常在 URI 中增加一段用于标识版本,例如/v1/v2等。例如:

复制代码
curl https://example.com/api/v2/lists/3

这种方式的优势在于版本信息很容易明显的看出来,可以通过浏览器直接访问。

HTTP 头中设置版本

这种方式的版本信息会放在 HTTP 的请求头中,通常会利用Accept字段,或者自定义一个字段。例如:

复制代码
curl https://example.com/api/lists/3 \
-H 'Accept: application/vnd.example.v2+json'

这种方式的好处是当版本升级时,URI 保持不变,并且仅用于表示资源定位。

没有版本

版本化的目的是为了标识 API 的变化,如果 API 不会变化,或者每次都会重新扩展新的 API,这种情况下,就可以标识版本信息。例如:

curl https://example.com/api/lists/3一种折中方案

前面提到了三种版本化 API 的方式,通常情况下需要针对自己业务的特殊性来挑选其中的一种方式。但是,在实际应用场景中,情况会更加复杂,API 的升级通常有两种情况:

  1. 大版本更新,例如字段类型变更、数据对象变更等。这种情况下无法满足对客户端的向下兼容,因此需要修改版本号。
  2. 小版本更新,例如增加可选参数、增加返回字段等。这种情况对于新客户端可以增加功能,对于老客户端仍然可以保持原有功能,可以不修改版本号。

因此,本文提出的折中方案是基于 URI 中的大版本号和 HTTP 头中的小版本号整合的方式。下面通过一个简单的示例来解释。

用户管理平台

一个常用的用户管理平台,提供以下 API,通过用户 ID 获取用户信息:

复制代码
curl https://example.com/api/v1/user/1
...
{
"id": 1,
"name": "test",
"email": "test@example.com"
}

考虑以下两种变动情况:一种是用户 id 从数字变成了字符串,另一种是新增一个用户头像的值。

前者修改因为数据类型的变化,会导致客户端解析出现问题。因此这样的修改已经破坏了向下兼容性,此时就需要修改 API 的版本号。例如:

复制代码
curl https://example.com/api/v2/user/1
...
{
"id": "1",
"name": "test",
"email": "test@example.com"
}

第二种情况,对于旧客户端来说,只是增加了不使用的字段,通常的 JSON 格式解析库都可以忽略这些不使用的字段。对于新客户端则可以读取新的字段。例如:

复制代码
curl https://example.com/api/v2/user/1
...
{
"id": "1",
"name": "test",
"email": "test@example.com",
"avatar": "http://example.com/1.jpg"
}

这种情况下,基本可以做到向下兼容,因此可以算是“小版本升级”。针对小版本升级,可以将小版本号放到 HTTP 头中。例如:

复制代码
curl https://example.com/api/v2/user/1 \
-H 'API-VERSION: 20170801'
...
{
"id": "1",
"name": "test",
"email": "test@example.com",
"avatar": "http://example.com/1.jpg"
}

后端路由

由于混合版本化的方式同时涉及到 URI 和 HTTP 头字段,前端代理(例如 HAProxy、nginx)可以通过这些特定版本号字段将请求代理到对应的后端应用。

例如,前端使用 HAProxy 进行多版本分发,可以针对 URI 和 HTTP 头定制 acl,然后再对这些 acl 进行组合,设置不同的 backend。

复制代码
acl is_v1 path_beg /api/v1
acl is_v2 path_beg /api/v2
acl is_version_1 hdr(API-VERSION) 20170801
acl is_version_2 hdr(API-VERSION) 20170701
use_backend old_server if is_v1 is_version_1
use_backend new_server if is_v2 is_version_2
backend old_server
...
backend new_server
...

这样可以将 API 版本化规则应用到不同的后端,以保证向下兼容性。

总结

基于本文版本化 API 规则,将“大版本”应用在 URI 上,将“小版本”应用在 HTTP 头字段上。通常来说,如果 API 升级之后破坏了向下兼容性,就应该升级“大版本”号;如果 API 升级可以向下兼容,可以升级“小版本”号。

版本化 API 有很多不同的设计方式,本文仅是其中一种。实际应用时,还是要根据业务场景进行选择,包括 API 版本升级频率,API 稳定性等。通过 HAProxy、nginx 等代理服务,可以在确保向下兼容的情况下,由业务方决定老版本 API 的保留时间。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-09-11 19:008065

评论

发布
暂无评论
发现更多内容

云小课 | SA基线检查---给云服务的一次全面“体检”

华为云开发者联盟

态势感知 华为云 基线检查 上云合规 全面体检

040022-week4-design

InfoQ_70156470130f

模块四作业

小鹿

第四模块-考试试卷存储方案设计

🌾🌾🌾小麦🌾🌾🌾

架构实战营

openLooKeng视图详解

openLooKeng

大数据 openLooKeng

并发高?可能是编译优化引发有序性问题

华为云开发者联盟

Java 编译 代码 并发 指令

【架构实战营】模块四作业

liu🍊

千万级学生管理系统的考试试卷存储方案

奔奔

vue3 学习笔记 (二)——axios 的使用有变化吗?

码仔

axios Vue 3

高级可视化神器Plotly绘制热力图

Peter

可视化 plotly

金融级数据库新坐标:腾讯云TDSQL发布全自研新敏态引擎

腾讯云数据库

数据库 tdsql

架构训练营 - 模块四作业

VegetableBird

架构实战营 #架构实战营 架构师实战营 「架构实战营」

dart系列之:在dart中使用生成器

程序那些事

flutter dart 程序那些事 生成器模式 11月日更

入驻快讯 | 欢迎TDengine正式入驻 InfoQ 写作平台!

InfoQ写作社区官方

入驻快讯

嵌入式系统软件开发:你需要知道的一切

龙智—DevSecOps解决方案

嵌入式系统 嵌入式系统软件开发

试卷存储方案设计

zjluoyue

模块四作业提交

21°Char

中科柏诚本地生活,率先发力场景金融新营销模式

联营汇聚

分析师机构发布中国低代码平台现状分析报告,华为云AppCube为数字化转型加码

华为云开发者联盟

低代码 数字化 华为云 低代码平台 AppCube

TDSQL | 云时代,我们到底需要怎样的数据库?

腾讯云数据库

数据库 tdsql

iOS开发:个人整理的关于UITableViewCell的常用属性的知识

三掌柜

11月日更

不止承上启下,带你了解工业物联网关

华为云开发者联盟

物联网 边缘计算 网关 工业物联网 工业物联网关

vivo统一告警平台建设与实践

vivo互联网技术

软件架构设计 运维监控 告警系统

架构师实战营 - 模块四 - 作业

lucian

架构师实战营

架构训练营 模块四 作业

dog_brother

「架构实战营」

Android C++系列:Linux进程(二)

轻口味

c++ android jni 11月日更

在120篇系列专栏中,才能学会 python beautifulsoup4 模块,7000字博客+爬第九工场网

梦想橡皮擦

11月日更

大厂算法面试之leetcode精讲3.动态规划

全栈潇晨

LeetCode 算法面经 算法面试

Hadoop 入门笔记—核心组件 YARN

恒生LIGHT云社区

大数据 hadoop YARN

最强最全面的数仓建设规范指南(二)

五分钟学大数据

11月日更

Elasticsearch 倒排索引详细剖析

大数据技术指南

11月日更

如何版本化你的API?_架构_金灵杰_InfoQ精选文章