原文地址:http://www.infoq.com/cn/news/2017/09/How-versioning-API前端
如何版本化API須要考慮各類實際業務場景,可是一個完備的API應該是:nginx
爲了知足上述約定,版本化API不失爲一種保持兼容性的好方法。版本化API的一般方式有:json
URI中設置版本後端
這種方式一般在URI中增長一段用於標識版本,例如/v1
、/v2
等。例如:api
curl https://example.com/api/v2/lists/3
這種方式的優點在於版本信息很容易明顯的看出來,能夠經過瀏覽器直接訪問。瀏覽器
HTTP頭中設置版本app
這種方式的版本信息會放在HTTP的請求頭中,一般會利用Accept
字段,或者自定義一個字段。例如:curl
curl https://example.com/api/lists/3 \ -H 'Accept: application/vnd.example.v2+json'
這種方式的好處是當版本升級時,URI保持不變,而且僅用於表示資源定位。url
沒有版本設計
版本化的目的是爲了標識API的變化,若是API不會變化,或者每次都會從新擴展新的API,這種狀況下,就能夠標識版本信息。例如:
curl https://example.com/api/lists/3
一種折中方案
前面提到了三種版本化API的方式,一般狀況下須要針對本身業務的特殊性來挑選其中的一種方式。可是,在實際應用場景中,狀況會更加複雜,API的升級一般有兩種狀況:
所以,本文提出的折中方案是基於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的保留時間。