API Versioning
Why?
发布出去的 API 就像泼出去的水,不进行版本控制,对某些调用者来说一定会是灾难性的。
举个例子。比如你在一家公司负责后端 API 的开发,同时给公司的 Android 和 iOS 客户端提供接口。 在 1 月份的时候,你开发了一个接口,用于获取文章的详情
@GET /post/:id
//response
{
"title": "xxx",
"content": "xxx",
"author": {
"id": 123,
"name": "xxx"
}
}
开发完成后,你很 happy 地告诉客户端同学,获取文章详情就调我这个接口吧,一点问题都没有。客户端同学也很 happy 地调用了。2 月份,客户端开发完成,顺利发布 1.0 版本。这个时候,还没有遇到任何问题。
3 月份的时候,设计变了,文章支持了多作者!所以现在那个相同的 API 返回的结果可能是这样的,
@GET /post/:id
// response
{
"title": "xxx",
"content": "xxx",
"author": [
{
"id": 123,
"name": "xxx"
},
{
"id": 456
"name": "xxx"
}
]
}
Boom! 这下可糟了,如果 API 产生了这么重大的变化,那么已经发出去的 1.0 版本的客户端可怎么办啊?(开发过客户端的同学都知道,同一个接口返回这么「脏」的数据是会 crash 的)。这个时候,就需要 API versioning(版本化)了。
How?
通常来说,API 版本控制有以下几种方式:
/api/v1/xxx
直接把 API 的版本信息放到 URL 里面,新浪是这么做的。
优点:直观 缺点:URL 被污染了,很不优雅
API-VERSION: 3.0
使用自定义的 header 识别 API 的版本,知乎目前是这么做的。
优点:URL 变得很干净 缺点:不直观,代码不好组织,而且容易产生向后兼容的问题(至少知乎的某些 API 是这样的,一般这种对于 header 的修改都是全局的,某些 API 说好了可以升级到 2.0,但是我调用 2.0 的
/singin
都登录不上)Accept: application/vnd.xxx.v2+json
修改 header 中的
Accept
字段,Github 是这么做的。优缺点同上