團隊內部RestAPI開發採用設計驅動開發的模式,即便用API設計文檔解耦前端和後端的開發過程,雙方只在聯調與測試時耦合。在實際開發和與前端合做的過程當中,受限於衆多因素的影響,開發效率還有進一步提升的空間。本文的目的是優化工具鏈支持,減小一部分重複和枯燥的勞動。php
根據我的的開發經驗,後端編寫API設計文檔時常見的狀況有:若是是簡單的需求,API數量較少,後端直接經過內部即時通訊軟件和前端溝通;若是是複雜的需求,API數量較多,後端會先把API描述寫到本地臨時文檔(純文本、markdown、evernote等)或者內網(內部我的Wiki、git倉庫)中,而後把連接發給前端review或者直接面對面溝通。這樣的方式靈活,但存在一些問題,好比:html
描述格式沒有標準。對於簡單的描述,文檔格式比較隨意,雙方基於約定和經驗理解和開發1;完備的描述,編寫文檔所需時間較長,而且細節複雜(須要考慮不一樣的HTTP請求類型、HTTP頭部信息、HTTP請求內容等),高質量地建立這份文檔自己就是件很是吃力的事,下游的抱怨聲不絕於耳。固然在合做開發中,文檔越完備,雙方的理解誤差就越少、開發產生的bug就越少,後期也更容易維護代碼、適應人員變動,可是編寫完備的文檔所須要的額外時間也不容忽視,沒有代碼產出的設計文檔可能不得已讓位於現實中總體開發時間的緊張。前端
以開發「得到管理員帳戶下可用商戶」爲例。若是是簡單的描述,後端告知前端url爲{host}/ajax/shop
,返回的結構是[{"shopId":int,"shopName":string}]
,有經驗的前端會自動判斷出Method
爲Get
,Content-type
爲application/json
,request不須要附帶參數,不須要對錯誤值作特殊處理;而若是是複雜的描述,後端通常會列出 API名稱、功能描述、調用方式、請求參數、請求示例、返回值、成功的返回結果示例、失敗的返回結果示例中的幾項,填充到已有的API模板中 2。
輸入效率不高。因爲開發的API模板缺少固定的標準,所以只能在例如Wiki、純文本編輯器、markdown編輯器中編寫,沒法獲得現代IDE中語法高亮、自動補全、錯誤提示等特性的支持,總體感受就像是在記事本中寫Java。java
> 舉例:需求要求開發一個新增優惠券API,其樣例數據只能由開發手動生成。若是是修改已有的API,要補充新的樣例數據,開發通常會登陸商戶平臺,打開優惠券頁面,在Chrome中實際操做一遍,抓包獲得request的body(json格式),在json格式化網站(如[json.cn](json.cn))美化後複製到API設計文檔中。![clipboard.png](/img/bVTWta)
重複錄入。由於文檔庫功能羸弱,使用不便,因此開發通常先按本身的格式寫一份文檔,可是若是不直接把API錄入到公司文檔庫,則開發須要對一份API出兩份設計文檔。開發通常會開兩個窗口,左邊是API設計文檔的完成件,右邊是公司API文檔庫編輯頁面,而後把左邊格式各異的API描述文本轉換到右邊統一的markdown格式。git
例如:想象一下從Wiki文檔的表格中一個個複製粘貼,再編輯成markdown格式文本是典型的成本大於收益的工做。
文檔維護成本大。因爲文檔和代碼分開存放,因爲須要手動操做,所以文檔與代碼同步成本較高。隨着時間推移,不斷修改接口實現的時候都必須同步修改接口文檔,而文檔與代碼又處於兩個不一樣的媒介,除非有嚴格的管理機制,否則很容易致使不一致現象,並在業務總體交接、開發成員替換時使後來人付出較大的時間成本。github
不一樣的存放形式的優缺點見仁見智,相似於Spring也有XML和JavaConfig兩種配置方式。
缺乏樣例數據。因爲團隊內部前端通常不會全面的瞭解業務,後端提供的樣例數據每每比前端本身生成的Mock數據對業務需求的把握更準確。若是後端能在API設計文檔中提供樣例數據,一是若是前端沒有自動Mock工具的話,能節約前端生成Mock數據的時間;二是能在聯調前爲前端提早發現一些低級錯誤(好比具備業務特徵的一些默認值處理、空值處理、字段缺失等場景)。ajax
beta環境綁定了惟一的beta域名,所以在多分支並行開發時是稀缺資源,較大的項目在beta環境編譯和部署每每消耗不少等待和解決衝突的時間。若是在聯調中發現的問題較多,就須要屢次部署beta環境,時間成本十分可觀。spring
如何減小部署時間另外行文
總結起來,上面列出的問題大部分是因爲API描述標準不統一引發的,所以要用標準化的工廠代替散亂的手工生產。雖然平時開發的API具備Rest風格、對外網開放,只被企業本身的應用調用,不過廣泛的WebAPI開發流程仍是適用的。我在網上搜索一些功能較爲符合的RestAPI設計工具,將其大體分爲3類討論。
json
人和機器可讀的API描述標準,圍繞該語言有完善的工具鏈:通常有設計、編譯(即Codegen)、測試(有MockServer、自動Mock、本地直連等形式)、文檔(包括靜態文檔,如html和pdf;還有可交互文檔html+js)、合做(多人+多角色合做開發)這幾個模塊,各個標準都差很少。segmentfault
較爲學術性的表述:雖然Web API的實現正變得愈來愈普及,但在工具方面還缺少一些被普遍接受的標準,用以描述、發現,而且理解大量基於API的服務的意義。Web API之「元語言」有三個關鍵領域:API描述、API發現以及API檔案。所謂的API描述,指的是以一種讓人類與機器均可讀的形式對API進行描述,包括API的實現細節,例如資源與URL、表述格式(HTML、XML、JSON等等)、狀態碼以及輸入參數。
Swagger、Apiary、RAML的格式各自採起了一種略有不一樣的設計方式,但在本質上都提供了相同的基本特性:以多種不一樣級別的細節對Web API進行描述。
以Swagger23爲例,分爲5個部分(示例圖來自於RAML,不過功能都差很少)。
OpenAPI
(前身是Swagger API Spec
),提供強大的在線編輯功能,包括語法高亮、錯誤提示、自動完成、實時預覽4,而且支持用戶以Json、Yaml格式撰寫5、導入、導出、轉換文檔。Spring Boot
構建,生成的代碼包括定義的API接口、空實現方法的樣板代碼、業務POJO、配套的Swagger註解。值得注意的是,由自動生成的Swagger註解,能夠反向生成最初的API設計文檔SwaggerHub
中提供收費的在線測試功能,主要有MockServer(Auto Mocking
)、問題跟蹤(Issue Tracking
)SwaggerHub
能夠配合API版本,自動同步相應文檔的版本SwaggerHub
提供團隊管理、聯調開發、文檔標註等多人合做開發的支持再提一下Apiary和RAML。Apiary6使用API Blueprint
標準,Apiary網站提供了在線編輯、實時預覽、Mock、可交互文檔、團隊合做、Github同步、流量追蹤等包含整個API生命週期的全部服務,固然這是收費產品,並且價格不菲;另外,用戶也能夠經過開源的命令行工具進行離線的API設計、文檔生成、發佈過程,並將其集成到本身的工做流中,這也是它的一大特色。RAML使用RAML1.0
標準,沒有本身的可視化在線開發平臺,而是用官方或第三方的離線工具(如API Workbench
系列)來代替,所以它也存在一些缺點,好比:工具更新不及時,某些Tool不支持最新的RAML1.0
。
相似於Intellij Idea的生成JavaDoc
功能,是一種註釋解析器,從C++、Java、Python代碼註釋中基於特定的關鍵字(如@param
、@return
)生成API靜態文檔。因爲更像是先代碼實現後生成API文檔,因此不能算做是設計驅動的開發;另外apidocjs也缺少IDE支持。
沒有公開的API設計語言,提供在線或離線、閉源或開源的可視化、一體化API開發平臺。這裏選擇中文的Rap、eolinker做爲表明。Rap是阿里的開源做品,也提供線上服務,核心功能是文檔編輯和自動Mock服務。eolinker是綜合的接口管理平臺,除了常見的功能,還提供接口商店、數據字典等適合創業團隊快速開發API的特性。在此不作進一步介紹。
Swagger2 | API Blueprint | RAML | |
---|---|---|---|
Design | 在線編輯、IntelliJ Idea插件 | 在線編輯、命令行、Sublime/Atom/Vim插件 | API Workbench、Sublime/VS插件 |
Design文檔格式 | yaml、json | markdown | yaml |
Build支持 | 在線Build、IntelliJ Idea插件 | / | Maven插件 |
Codegen服務端框架 | Spring Boot | / | JAX—RS |
Test | 運行時手動Mock、第三方工具 | 官方和第三方工具生成MockServer/Client | 第三方工具和在線服務 |
Document | Maven插件生成靜態文檔、在線或運行時生成可交互文檔,支持SpringMVC+註解形式 | 第三方工具 | 第三方工具 |
Share | 在線、收費 | 在線、收費 | 離線、第三方工具 |
綜合考慮,最後選擇Swagger2。由於Swagger對現有的工做流侵入較少;工具較爲完整;與團隊使用的Spring MVC
技術棧無縫集成,能夠減輕文檔工做量。Swagger2也有一些缺點,如:使用註解方式對代碼有侵入性。
減小文檔的編寫時間
OpenAPI
規定的關鍵字。Controller
類和相關方法上(以Spring MVC
和Spring Boot
爲例),便可以經過Java反射在Maven Complie
或運行時生成API設計文檔。Swagger有Intellij Idea
的插件支持,Swagger註解則能利用現代Java IDE的特性,提升輸入效率;另外完善的註解也方便其餘開發人員進行後期維護,不須要在設計文檔和代碼實現中來回切換查看。此種方式至關於面向規約的開發模式,即先規定接口,再填充實現。 API Blueprint
的markdown格式能夠存儲到公司的API文檔庫,html靜態文檔能夠存儲到內部Wiki。Maven + Spring Boot
的服務端代碼,不過生成的POJO和Controller類的命名可能不太理想,須要本身調整。Spring MVC
)先創建RestController類、相應的API空方法、POJO做爲骨架。對應的API設計文檔見文末的Reference
節。
@Api("Users") @RestController @RequestMapping(value = "/users") public class UserController { @ApiOperation(value = "建立用戶", notes = "根據User對象建立用戶") @PostMapping public String postUser(@RequestBody User user) { return null; } @ApiOperation(value = "獲取用戶詳細信息", notes = "根據url的id來獲取用戶詳細信息") @GetMapping("/{id}") public User getUser(@PathVariable Long id) { return null; } } class User{ private Long id; private String name; private String age; //getter,setter }
生成的具體方式按照耗時長短排列爲:Maven Complie
、Test Case、Server Runtime。可在Swagger Editor中預覽相應的可交互文檔。根據前端的反饋,修改Swagger註解,並把新的文檔存儲到內部Wiki或者API文檔庫(若是改動量大的話,利用Diff工具提升效率)。
開發完成後啓動Server,Swagger-UI的訪問地址爲http://localhost:8080/swagger-ui.html
爲了減小beta環境的衝突、加快部署速度,最好在本地開發環境聯調。
swagger: '2.0' info: description: Click Link Below for Help version: v1 title: demo13 termsOfService: 'http://www.github.com/kongchen/swagger-maven-plugin' host: HOST basePath: /s tags: - name: Users schemes: - http paths: /users: post: tags: - Users summary: 建立用戶 description: 根據User對象建立用戶 operationId: postUser parameters: - in: body name: body required: false schema: $ref: '#/definitions/User' responses: '200': description: successful operation schema: type: string '/users/{id}': get: tags: - Users summary: 獲取用戶詳細信息 description: 根據url的id來獲取用戶詳細信息 operationId: getUser parameters: - name: 'id' in: path required: true type: integer format: int64 responses: '200': description: successful operation schema: $ref: '#/definitions/User' definitions: User: type: object properties: id: type: integer format: int64 name: type: string age: type: string