【效率專精系列】善用API統一描述語言提升RestAPI開發效率

團隊內部RestAPI開發采用設計驅動開發的模式,即使用API設計文檔解耦前端和后端的開發過程,雙方只在聯調與測試時耦合。在實際開發和與前端合作的過程中,受限于眾多因素的影響,開發效率還有進一步提高的空間。本文的目的是優化工具鏈支持,減少一部分重復和枯燥的勞動。

現狀梳理

前后端工作流

  1. 需求理解:前后端先理解產品思路、需求的詳細內容
  2. 敲定接口:后端出API設計文檔初稿,與前端面對面或者在線討論修正,接著后端(有時是前端)把API描述記錄到公司內部的API文檔庫(在線markdown編輯器,提供分級目錄的存儲功能,對如何描述API沒有一定的標準,因此描述格式不統一,因人而異1)。接著根據雙方工作的安排,約定聯調時間
  3. 獨立開發:雙方獨立開發(也有可能非完全獨立開發,如需要對方的環境配合等;或者存在返工,如API設計發生變更等)
  4. 系統聯調:測試API基本功能和雙方系統的連通性
  5. 測試回歸:開發或者QA編寫測試用例并測試業務流程

可優化方向

1. 減少文檔編寫時間

根據個人的開發經驗,后端編寫API設計文檔時常見的情況有:如果是簡單的需求,API數量較少,后端直接通過內部即時通信軟件和前端溝通;如果是復雜的需求,API數量較多,后端會先把API描述寫到本地臨時文檔(純文本、markdown、evernote等)或者內網(內部個人Wiki、git倉庫)中,然后把鏈接發給前端review或者直接面對面溝通。這樣的方式靈活,但存在一些問題,比如:

  • 描述格式沒有標準。對于簡單的描述,文檔格式比較隨意,雙方基于約定和經驗理解和開發1;完備的描述,編寫文檔所需時間較長,并且細節復雜(需要考慮不同的HTTP請求類型、HTTP頭部信息、HTTP請求內容等),高質量地創建這份文檔本身就是件非常吃力的事,下游的抱怨聲不絕于耳。當然在合作開發中,文檔越完備,雙方的理解偏差就越少、開發產生的bug就越少,后期也更容易維護代碼、適應人員變更,但是編寫完備的文檔所需要的額外時間也不容忽視,沒有代碼產出的設計文檔可能不得已讓位于現實中整體開發時間的緊張。

    以開發“獲得管理員賬戶下可用商戶”為例。如果是簡單的描述,后端告知前端url為{host}/ajax/shop,返回的結構是[{"shopId":int,"shopName":string}],有經驗的前端會自動判斷出MethodGetContent-typeapplication/json,request不需要附帶參數,不需要對錯誤值做特殊處理;而如果是復雜的描述,后端一般會列出API名稱、功能描述、調用方式、請求參數、請求示例、返回值、成功的返回結果示例、失敗的返回結果示例中的幾項,填充到已有的API模板中2
  • 輸入效率不高。由于開發的API模板缺乏固定的標準,因此只能在例如Wiki、純文本編輯器、markdown編輯器中編寫,無法得到現代IDE中語法高亮、自動補全、錯誤提示等特性的支持,整體感覺就像是在記事本中寫Java。

    • 設計文檔中會規定API輸出的數據結構(一般為json數組或者json對象),如果數據結構較為復雜(比如包含有幾十個字段的POJO),要在設計文檔中書寫可讀性良好的數據結構需要更多的時間;如果數據結構中字段缺失或者可讀性差,則會影響前端的文檔理解和代碼開發。
    • 如果后端能提供樣例數據自然是最好的,因為后端最熟悉業務邏輯,產生的樣例數據比前端自己Mock的數據更好。但是復雜數據結構的樣例數據的編寫同樣很花時間。
> 舉例:需求要求開發一個新增優惠券API,其樣例數據只能由開發手動生成。如果是修改已有的API,要補充新的樣例數據,開發一般會登錄商戶平臺,打開優惠券頁面,在Chrome中實際操作一遍,抓包得到request的body(json格式),在json格式化網站(如[json.cn](json.cn))美化后復制到API設計文檔中。![clipboard.png](/img/bVTWta)
  • 重復錄入。因為文檔庫功能羸弱,使用不便,所以開發一般先按自己的格式寫一份文檔,但是如果不直接把API錄入到公司文檔庫,則開發需要對一份API出兩份設計文檔。開發一般會開兩個窗口,左邊是API設計文檔的完成件,右邊是公司API文檔庫編輯頁面,然后把左邊格式各異的API描述文本轉換到右邊統一的markdown格式。

    例如:想象一下從Wiki文檔的表格中一個個復制粘貼,再編輯成markdown格式文本是典型的成本大于收益的工作。
  • 文檔維護成本大。由于文檔和代碼分開存放,由于需要手動操作,因此文檔與代碼同步成本較高。隨著時間推移,不斷修改接口實現的時候都必須同步修改接口文檔,而文檔與代碼又處于兩個不同的媒介,除非有嚴格的管理機制,不然很容易導致不一致現象,并在業務整體交接、開發成員替換時使后來人付出較大的時間成本。

    不同的存放形式的優缺點見仁見智,類似于Spring也有XML和JavaConfig兩種配置方式。

2. 減少聯調時間

缺少樣例數據。由于團隊內部前端一般不會全面的了解業務,后端提供的樣例數據往往比前端自己生成的Mock數據對業務需求的把握更準確。如果后端能在API設計文檔中提供樣例數據,一是如果前端沒有自動Mock工具的話,能節約前端生成Mock數據的時間;二是能在聯調前為前端提前發現一些低級錯誤(比如具有業務特征的一些默認值處理、空值處理、字段缺失等場景)。

3. 減少部署時間

beta環境綁定了唯一的beta域名,因此在多分支并行開發時是稀缺資源,較大的項目在beta環境編譯和部署往往消耗很多等待和解決沖突的時間。如果在聯調中發現的問題較多,就需要多次部署beta環境,時間成本十分可觀。

如何減少部署時間另外行文

尋找技術候選

總結起來,上面列出的問題大部分是由于API描述標準不統一引起的,因此要用標準化的工廠代替散亂的手工生產。雖然平時開發的API具有Rest風格、對外網開放,只被企業自己的應用調用,不過普遍的WebAPI開發流程還是適用的。我在網上搜索一些功能較為符合的RestAPI設計工具,將其大致分為3類討論。
clipboard.png

第一類:Swagger、Apiary、RAML

人和機器可讀的API描述標準,圍繞該語言有完善的工具鏈:一般有設計、編譯(即Codegen)、測試(有MockServer、自動Mock、本地直連等形式)、文檔(包括靜態文檔,如html和pdf;還有可交互文檔html+js)、合作(多人+多角色合作開發)這幾個模塊,各個標準都差不多。

較為學術性的表述:雖然Web API的實現正變得越來越普及,但在工具方面還缺乏一些被廣泛接受的標準,用以描述、發現,并且理解大量基于API的服務的意義。Web API之“元語言”有三個關鍵領域:API描述、API發現以及API檔案。所謂的API描述,指的是以一種讓人類與機器都可讀的形式對API進行描述,包括API的實現細節,例如資源與URL、表述格式(HTML、XML、JSON等等)、狀態碼以及輸入參數。
Swagger、Apiary、RAML的格式各自采取了一種略有不同的設計方式,但在本質上都提供了相同的基本特性:以多種不同級別的細節對Web API進行描述。

以Swagger23為例,分為5個部分(示例圖來自于RAML,不過功能都差不多)。
clipboard.png

  • Design:其標準為OpenAPI(前身是Swagger API Spec),提供強大的在線編輯功能,包括語法高亮、錯誤提示、自動完成、實時預覽4,并且支持用戶以Json、Yaml格式撰寫5、導入、導出、轉換文檔。
  • Build:設計文檔可以編譯成客戶端和服務端,支持的語言包括Java、NodeJS、C++等主流語言。其中Java服務器端使用流行的Spring Boot構建,生成的代碼包括定義的API接口、空實現方法的樣板代碼、業務POJO、配套的Swagger注解。值得注意的是,由自動生成的Swagger注解,可以反向生成最初的API設計文檔
  • Test:可在本地服務器運行時使用本地測試功能;用戶也可以使用SwaggerHub中提供收費的在線測試功能,主要有MockServer(Auto Mocking)、問題跟蹤(Issue Tracking
  • Document:可以在線或離線(包括代碼編譯時和運行時)地生成靜態html、pdf等文檔;SwaggerHub可以配合API版本,自動同步相應文檔的版本
  • ShareSwaggerHub提供團隊管理、聯調開發、文檔標注等多人合作開發的支持

再提一下Apiary和RAML。Apiary6使用API Blueprint標準,Apiary網站提供了在線編輯、實時預覽、Mock、可交互文檔、團隊合作、Github同步、流量追蹤等包含整個API生命周期的所有服務,當然這是收費產品,而且價格不菲;另外,用戶也可以通過開源的命令行工具進行離線的API設計、文檔生成、發布過程,并將其集成到自己的工作流中,這也是它的一大特點。RAML使用RAML1.0標準,沒有自己的可視化在線開發平臺,而是用官方或第三方的離線工具(如API Workbench系列)來代替,因此它也存在一些缺點,比如:工具更新不及時,某些Tool不支持最新的RAML1.0

第二類:Apidocjs

類似于Intellij Idea的生成JavaDoc功能,是一種注釋解析器,從C++、Java、Python代碼注釋中基于特定的關鍵字(如@param@return)生成API靜態文檔。由于更像是先代碼實現后生成API文檔,所以不能算作是設計驅動的開發;另外apidocjs也缺乏IDE支持。

第三類:Rap、eolinker

沒有公開的API設計語言,提供在線或離線、閉源或開源的可視化、一體化API開發平臺。這里選擇中文的Rap、eolinker作為代表。Rap是阿里的開源作品,也提供線上服務,核心功能是文檔編輯和自動Mock服務。eolinker是綜合的接口管理平臺,除了常見的功能,還提供接口商店、數據字典等適合創業團隊快速開發API的特性。在此不做進一步介紹。

如何選型?

選型邏輯

  1. 社區活躍、功能完善,應用成熟。
  2. 學習成本低、上手時間短。作為業務開發,缺少時間熟悉學習曲線陡峭的知識和工具。
  3. 功能較多地契合上述優化方向。
  4. 能補充現有工作流的不足,不做大范圍的代替。
  5. 要考慮測試環境處于內網造成的障礙。

初步分析

  1. rap、eolinker、swaggerHub、apiary提供了一整套API開發環境,取代了現有工作流。放棄。
  2. apidocjs缺乏現代IDE特性支持,輸入效率較低。放棄。

進一步分析

Swagger2API BlueprintRAML
Design在線編輯、IntelliJ Idea插件在線編輯、命令行、Sublime/Atom/Vim插件API Workbench、Sublime/VS插件
Design文檔格式yaml、jsonmarkdownyaml
Build支持在線Build、IntelliJ Idea插件/Maven插件
Codegen服務端框架Spring Boot/JAX—RS
Test運行時手動Mock、第三方工具官方和第三方工具生成MockServer/Client第三方工具和在線服務
DocumentMaven插件生成靜態文檔、在線或運行時生成可交互文檔,支持SpringMVC+注解形式第三方工具第三方工具
Share在線、收費在線、收費離線、第三方工具

綜合考慮,最后選擇Swagger2。因為Swagger對現有的工作流侵入較少;工具較為完整;與團隊使用的Spring MVC技術棧無縫集成,可以減輕文檔工作量。Swagger2也有一些缺點,如:使用注解方式對代碼有侵入性。

用Swagger2優化現有工作流

  1. 減少文檔的編寫時間

    1. 如果后端先編寫獨立的API設計文檔,可利用Swagger在線編輯器或IDE插件的自動完成等特性;yaml格式統一、簡單易懂、表達能力強,較markdown冗余字符更少。通過模仿官方Example很容易學習OpenAPI規定的關鍵字。
    2. 另外后端也可以把API設計文檔直接通過注解的形式,標注在Controller類和相關方法上(以Spring MVCSpring Boot為例),即可以通過Java反射在Maven Complie或運行時生成API設計文檔。Swagger有Intellij Idea的插件支持,Swagger注解則能利用現代Java IDE的特性,提高輸入效率;另外完善的注解也方便其他開發人員進行后期維護,不需要在設計文檔和代碼實現中來回切換查看。此種方式相當于面向規約的開發模式,即先規定接口,再填充實現。
  2. 減少文檔的轉換時間:利用第三方工具實現從Swagger、API Blueprint、RAML格式的互相轉換,或者直接輸出為html靜態文檔,方便整合到現在的工作流中。比如:API Blueprint的markdown格式可以存儲到公司的API文檔庫,html靜態文檔可以存儲到內部Wiki。
  3. 減少(可能的)開發時間:如果已有獨立的API設計文檔,在Swagger Editor中生成基于Maven + Spring Boot的服務端代碼,不過生成的POJO和Controller類的命名可能不太理想,需要自己調整。
  4. 減少聯調時間:后端可以在設計文檔或注解中指定API或者POJO的Example數據,節約前端手動編寫Mock數據的時間。

附錄1:流程實例演示(腳手架為Spring MVC

1. 標注相應的Swagger注解作為API設計文檔

先建立RestController類、相應的API空方法、POJO作為骨架。對應的API設計文檔見文末的Reference節。

@Api("Users")
@RestController
@RequestMapping(value = "/users")
public class UserController {@ApiOperation(value = "創建用戶", notes = "根據User對象創建用戶")@PostMappingpublic 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
}

2. 生成API設計文檔

生成的具體方式按照耗時長短排列為:Maven Complie、Test Case、Server Runtime。可在Swagger Editor中預覽相應的可交互文檔。根據前端的反饋,修改Swagger注解,并把新的文檔存儲到內部Wiki或者API文檔庫(如果改動量大的話,利用Diff工具提高效率)。
clipboard.png

3. 在Swagger-UI提供的可視化頁面中完成自測

開發完成后啟動Server,Swagger-UI的訪問地址為http://localhost:8080/swagger-ui.html

clipboard.png

4. 與前端聯調

為了減少beta環境的沖突、加快部署速度,最好在本地開發環境聯調。

附錄2:Swagger配置與使用

【5分鐘指南】Swagger2環境配置與使用

附錄3:YAML格式的API描述文檔示例

swagger: '2.0'
info:description: Click Link Below for Helpversion: v1title: demo13termsOfService: 'http://www.github.com/kongchen/swagger-maven-plugin'
host: HOST
basePath: /s
tags:- name: Users
schemes:- http
paths:/users:post:tags:- Userssummary: 創建用戶description: 根據User對象創建用戶operationId: postUserparameters:- in: bodyname: bodyrequired: falseschema:$ref: '#/definitions/User'responses:'200':description: successful operationschema:type: string'/users/{id}':get:tags:- Userssummary: 獲取用戶詳細信息description: 根據url的id來獲取用戶詳細信息operationId: getUserparameters:- name: 'id'in: pathrequired: truetype: integerformat: int64responses:'200':description: successful operationschema:$ref: '#/definitions/User'
definitions:User:type: objectproperties:id:type: integerformat: int64name:type: stringage:type: string

Reference

  1. Swagger:Rest API的描述語言
  2. RAML vs. Swagger vs. API Blueprint
  3. Springfox Reference Documentation
  4. Swagger使用
  5. swagger-maven-plugin
  6. 通過Swagger進行API設計,與Tony Tam的一次對話
  7. API 設計: RAML、Swagger、Blueprint三者的比較
  8. API描述、發現與檔案入門
  9. Spring Boot中使用Swagger2構建強大的RESTful API文檔
  10. API Design And Documentation
  11. Swagger與其他API文檔編寫工具對比

  1. 以“云打印機設置”中的一個API為例,簡單描述的典型。 clipboard.png?
  2. 自定義API模板。 clipboard.png?
  3. swagger的Design-Build-Document流程 clipboard.pngclipboard.png?
  4. 實時預覽。 clipboard.png?
  5. Swagger支持YAML格式。clipboard.png?
  6. Apiary的Design-Use-Implement流程。 clipboard.png?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/394340.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/394340.shtml
英文地址,請注明出處:http://en.pswp.cn/news/394340.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

leetcode劍指 Offer 14- I. 剪繩子(動態規劃)

給你一根長度為 n 的繩子,請把繩子剪成整數長度的 m 段(m、n都是整數,n>1并且m>1),每段繩子的長度記為 k[0],k[1]…k[m-1] 。請問 k[0]k[1]…*k[m-1] 可能的最大乘積是多少?例如,當繩子的…

數據包提取文件_航測怎樣高效提取無人機POS航點數據

無限創新工作室研發的POS數據記錄儀是一款采集飛控POS 數據并管理的設備,它將飛控 POS 點數據進行記錄,形成單獨的POS 數據記錄TXT 文本,并獨立存儲于內存卡,可通過USB、U 盤或內存卡形式對數據進行讀取。通過對相機進行拍照控制和…

點擊刪除表格中的行并提交到數據庫

html中&#xff1a; <el-table-column prop"operation" label"操作" width"170"> <template slot-scope"scope"> <el-button size"small" type"danger" click"deleteRow(scope.$index,s…

BZOJ 1878: [SDOI2009]HH的項鏈

1878: [SDOI2009]HH的項鏈 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3548 Solved: 1757[Submit][Status][Discuss]Description HH有一串由各種漂亮的貝殼組成的項鏈。HH相信不同的貝殼會帶來好運&#xff0c;所以每次散步 完后&#xff0c;他都會隨意取出一段貝殼&…

分布式 知乎 github_如何使用GitHub本機功能來幫助管理中型分布式團隊

分布式 知乎 githubby Alex Ewerlf由AlexEwerlf 如何使用GitHub本機功能來幫助管理中型分布式團隊 (How to use GitHub native features to help manage a mid-size distributed team) My team created a wiki page in our private Github repo about how we work on a common…

開始時間小于 結束時間 js_DNF分享紅包開始及結束時間 紅包有什么獎勵相關介紹...

[閩南網]DNF分享紅包分享快樂時間從2019年的1月3日開始到1月21日前結束&#xff0c;活動期間玩家每天登錄游戲可以得到一個新年紅包&#xff0c;使用后可以為同一個頻道的玩家送去祝福&#xff0c;根據送出紅包的數量得到不同的獎勵。(dnf幸運餃子鋪活動)(DNF95版新副本攻略)本…

文件的相關操作

將輸出的內容直接輸出到文件中去 &#xff1a;freopen( “1.txt” , "w" , stdout &#xff09;轉載于:https://www.cnblogs.com/ccut-ry/p/7456190.html

leetcode1504. 統計全 1 子矩形(動態規劃)

給你一個只包含 0 和 1 的 rows * columns 矩陣 mat &#xff0c;請你返回有多少個 子矩形 的元素全部都是 1 。 示例 1&#xff1a; 輸入&#xff1a;mat [[1,0,1], [1,1,0], [1,1,0]] 輸出&#xff1a;13 解釋&#xff1a; 有 6 個 1x1 的矩形。 有 2 個 1x2 的矩形。 有 3…

學plc好還是python好_PLC是學西門子的好還是學三菱的?

有人回復的很經典&#xff1a;“小孩子才會選擇&#xff0c;大人肯定是都要。”如果你是學生&#xff0c;或者正準備踏入這個行業&#xff0c;建議你先學西門子的博途&#xff0c;畢竟這個在國內用的人多些。但是&#xff0c;你要時刻記得&#xff0c;你的目標是星辰大海~~~不要…

wps如何自己制作流程圖_怎么制作流程圖,wps自動生成流程圖方法

在職場中我們要會熟練使用各種辦公軟件&#xff0c;才能提高我們的工作效率&#xff0c;下面我為大家分享三種制作流程圖的方法&#xff0c;非常簡單哦&#xff01;一&#xff0c;在Word中制作流程圖1&#xff0c;首先點擊“插入”再點擊“形狀”,點擊新建繪圖畫布&#xff0c;…

doom 源碼_Cartpole和Doom的策略梯度簡介

doom 源碼by Thomas Simonini通過托馬斯西蒙尼(Thomas Simonini) Cartpole和Doom的策略梯度簡介 (An introduction to Policy Gradients with Cartpole and Doom) This article is part of Deep Reinforcement Learning Course with Tensorflow ??. Check the syllabus here…

SQL 郵件配置篇

在我們運維工作中&#xff0c;經常要對備份&#xff0c;ETL等作業進行監控&#xff0c;這時我們需要用到SQL SERVER自帶的郵件服務器&#xff0c;其原理&#xff0c;我在這么里不多說&#xff0c;直接來實戰&#xff0c;下面是我對服務器配置源碼&#xff0c;分享給大家&#x…

選定用戶與用戶組啟動流程(學習筆記)

public class RepostoryServiceTest {private static final Logger LOGGER LoggerFactory.getLogger(RepostoryServiceTest.class);Rulepublic ActivitiRule activitiRule new ActivitiRule();Testpublic void testRepository(){//repositoryService最重要的功能就是對流程定…

python關于包的題怎么做_Python自定義包引入

python中的Module是比較重要的概念。常見的情況是&#xff0c;事先寫好一個.py文 件&#xff0c;在另一個文件中需要import時&#xff0c;將事先寫好的.py文件拷貝 到當前目錄&#xff0c;或者是在中增加事先寫好的.py文件所在的目錄&#xff0c;然后import。這樣的做法&#x…

汽車之家的安全框架,是如何從0到1搭建的?

“別人家的安全”是安全威脅情報&#xff08;微信ID&#xff1a;Threatbook&#xff09;近期推出的一檔專欄。 合規、管理、構建、應急……安全問題千千萬&#xff0c;層出不窮。我們沒辦法給出這些問題的標準答案&#xff0c;但我們可以用Case Study的形式&#xff0c;讓你看看…

leetcode264. 丑數 II

編寫一個程序&#xff0c;找出第 n 個丑數。 丑數就是質因數只包含 2, 3, 5 的正整數。 示例: 輸入: n 10 輸出: 12 解釋: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 個丑數。 說明: 1 是丑數。 n 不超過1690。 解題思路 直接用treeset去重和排序 代碼 class Solution …

vr多人_如何構建多人VR網絡應用

vr多人by Srushtika Neelakantam通過Srushtika Neelakantam 如何構建多人VR網絡應用 (How to build a multiplayer VR web app) In this article, we’ll learn about three great frameworks/libraries that allow any web developer to build a VR app that works on any de…

量子測量 -- 確定性的死神

一、測量 -- 確定性的死神 前文已反復提及在量子世界中測量這一過程會產生很多奇異的、反直覺的現象。在第一篇文章中我舉的例子是&#xff1a;用同樣的配方&#xff0c;同樣的火候&#xff0c;同樣的廚具&#xff08;所有你能想到的變量均相同&#xff09;煎雞蛋&#xff0c;結…

python增刪改查csv文件_Python--作業2--對員工信息文件,實現增刪改查操作

#!/usr/bin/env python#-*- coding:utf-8 -*-#Author:Huanglinshengimportos#查詢方式一&#xff1a;select * from data_staff.txt where age > 22#查詢方式二&#xff1a;select * from data_staff.txt where dept "IT"#查詢方式三&#xff1a;select * from d…

ios注銷所有通知_您一直想了解的有關iOS中通知的所有信息

ios注銷所有通知by Payal Gupta通過Payal Gupta 您一直想了解的有關iOS中通知的所有信息 (Everything you’ve always wanted to know about notifications in iOS) 漂亮的小警報..&#xff1f; (Pretty Little Alerts..?) Notifications are a way to inform users when new…