swagger可能是目前開發(fā)resful API時(shí)最流行的工具集,可能很多童鞋在遇到API開發(fā)需求時(shí),直接反應(yīng)會(huì)是:“用swagger不就好了?”。
protoapi與swagger會(huì)有一些理念上根本性差異,為詳細(xì)闡述這些差異,我們先來看看swagger是如何發(fā)展起來的。
文檔先行 vs 實(shí)現(xiàn)先行
swagger最早是在2011年開源,它處理提供的是:
-
機(jī)器可讀的
API JSON定義- 它后續(xù)又發(fā)展成為OpenAPI Specification
- 基于API實(shí)現(xiàn)代碼來生成
API JSON定義 - 基于
API JSON定義提供web界面,以:- 方便查看API文檔
- 快速測試API調(diào)用
- 基于
API JSON定義生成客戶端SDK
它核心的思路是API實(shí)現(xiàn)先行,即,先有服務(wù)器端的API的實(shí)現(xiàn)代碼,然后通過靜態(tài)分析這些實(shí)現(xiàn)代碼,去生成機(jī)器可讀的API JSON定義,以及文檔等等。
說白了,我們可以理解為這是服務(wù)器端開發(fā)人員,習(xí)慣于直接實(shí)現(xiàn)API,然后又懶得寫API文檔,在寫實(shí)現(xiàn)代碼的時(shí)候,順手寫一下注釋,然后使用swagger結(jié)合代碼 + 注釋生成出來文檔。
而protoapi強(qiáng)調(diào)的則是文檔先行,想要實(shí)現(xiàn)API的話,必須 先用protobuf作為IDL,把API先給定義好了,IDL即文檔,而且是人類可讀。
protobuf有嚴(yán)格的語法以及成熟的編譯器,當(dāng)然也是機(jī)器可讀的。
swagger code-gen
文檔先行與實(shí)現(xiàn)先行孰優(yōu)孰劣,這幾乎不需要討論,因?yàn)?code>swagger后續(xù)也推出了swagger-codegen項(xiàng)目,提倡文檔先行,即開發(fā)API的時(shí)候,先寫API JSON定義(我們也可以認(rèn)為這樣的API JSON定義是IDL),然后再使用swagger-codegen去分別生成服務(wù)器端已經(jīng)客戶端的SDK。
這樣的做法,其實(shí)跟protoapi的文檔/IDL先行非常類似,區(qū)別在于,swagger使用的是類似下面的機(jī)器可讀JSON格式:

人類去讀機(jī)器可讀的JSON格式,是很容易腦殼疼(前同事的評論)的,因此swagger又提供了Swagger Editor這樣的web編輯器。
而protoapi選擇的protobuf則是人類可讀的格式,各式文本編輯器、IDE均有其插件,可以方便的閱讀、編輯:

協(xié)作的差異
IDL是否方便閱讀、編輯其實(shí)還是小問題,重要的其實(shí)是對于團(tuán)隊(duì)協(xié)作的影響。
swagger更多是使用在提供給第三方調(diào)用的場景,比方說github。
在這樣的場景下,API提供些什么,完全是由服務(wù)器端實(shí)現(xiàn)者決定,他們在提供API的時(shí)候,其實(shí)也不會(huì)針對特定的業(yè)務(wù)場景,調(diào)用者會(huì)如何使用API,只有當(dāng)調(diào)用者開發(fā)具體業(yè)務(wù)的時(shí)候才會(huì)知曉。
并且,是API開發(fā)完畢、發(fā)布之后,API調(diào)用者的角色才會(huì)出現(xiàn)。
問題是,這樣的場景往往則跟公司內(nèi)部項(xiàng)目,特別是走前后端分離架構(gòu)的項(xiàng)目不符。
但我們?nèi)粘i_發(fā)公司內(nèi)部項(xiàng)目的時(shí)候,現(xiàn)實(shí)情況很可能是這樣:
- web前端、客戶端、后端API可能需要同時(shí)開發(fā)
- 實(shí)現(xiàn)的是新業(yè)務(wù),業(yè)務(wù)從項(xiàng)目開始就確定
- 后端提供的是特定業(yè)務(wù)的API,而不是通用、業(yè)務(wù)中立的API
- 調(diào)用方(web前端、客戶端)很可能更了解具體什么API更合適
在這樣的場景下,如果我們還是走swagger默認(rèn)所提倡的實(shí)現(xiàn)先行的開發(fā)模式,是非常不合適的:
- 調(diào)用方需要等待后端API開發(fā)完畢之后,才可以了解API
- 兩端無法并行開發(fā)會(huì)嚴(yán)重拖慢項(xiàng)目進(jìn)度
- 后端閉門造車提供的API未必最適合具體業(yè)務(wù)的需要
- 調(diào)用方難以推動(dòng)API變更
- 服務(wù)器后端,顧名思義是要有服務(wù)意識的
而如果采用protoapi這樣文檔/IDL先行方案,流程很可能是:
- 調(diào)用方定義特定業(yè)務(wù)需要的API,proto文件保存在獨(dú)立的代碼倉庫
- 后端、調(diào)用同時(shí)進(jìn)行開發(fā)
- API需要變更的時(shí)候,各方均可以對保存proto文件的代碼倉庫發(fā)起合并請求
這里,重點(diǎn)是將API定義,與API實(shí)現(xiàn)、API調(diào)用三者解耦剝離開來:
-
API定義先行,定義者可以是API實(shí)現(xiàn)方,也可以是調(diào)用方,更可以是第三方 - 有各方中立的具體形式方便各方協(xié)作推動(dòng)API的修改
這樣的開發(fā)方式更加符合敏捷流程。
總結(jié)一下
| protoapi | swagger | swagger-codegen | |
|---|---|---|---|
| 開發(fā)流程 | 文檔先行 | 實(shí)現(xiàn)先行 | 文檔先行 |
| 開發(fā)模式 | 敏捷開發(fā) | 瀑布流 | 偏瀑布流 |
| API定義者 | 前后端均可 | 后端 | 后端 |
| 變更流程友好 | 是 | 否 | 否 |
| IDL | 人類+機(jī)器可讀 | 偏機(jī)器可讀 | 偏機(jī)器可讀 |
| 前端代碼生成 | 有 | 有 | 有 |
| 后端代碼生成 | 有 | 無 | 有 |
我很久之前就使用過IDL去做各式代碼生成,并使用在之前公司幾乎所有的項(xiàng)目當(dāng)中,protoapi與我而言,并不是什么新穎的概念/實(shí)現(xiàn);而是成熟、經(jīng)歷過百項(xiàng)目長期考驗(yàn)的技術(shù)思路;相關(guān)的技術(shù)也都并不高深,屬于直接了當(dāng),明顯沒有bug的實(shí)現(xiàn)。
我一直沒有全面闡述過相關(guān)技術(shù)背后的理念。這次我重新整理寫這系列API的文章,反響最強(qiáng)烈的其實(shí)是客戶端、前端的多位前同事。
protoapi所提倡的是,是敏捷、流暢互動(dòng)的團(tuán)隊(duì)協(xié)作,而不是“我定義、你接受”這樣偏單向的流程。
后面我會(huì)整理一下protoapi的實(shí)戰(zhàn)案例,并將項(xiàng)目開源,暫時(shí)只是先在github上占個(gè)坑,歡迎star:github.com/yoozoo/protoapi