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 是这么做的。
优缺点同上

© Xinyu 2014 - 2024