Spring Boot介面文件自動生成最佳方案
背景
最近研發團隊需要做有狀態服務,需要複雜的yaml格式的資料抽象為物件,介面定義入參出參涉及的欄位多,物件多,介面文件編寫將是個麻煩事,尤其是前後端分離的開發模式下,維護好介面文件尤其重要。
手動維護介面文件,費時費力,而且介面可能改,前端拿到的文件可能已過期,可能造成許多不必要的麻煩,你可以想象你的前端同事想殺死你的表情,因此自動生成介面文件的方案尤為重要。
以下是幾種方案選型,文章結尾給出了我個人認為的最佳實踐。
Swagger-UI
官網連結地址:https://swagger.io
GitHub: https://github.com/swagger-api/swagger-ui
- 直接執行,可以線上測試 API 介面。
- 號稱世界上最流行的 API 框架。
- RESTFul API 文件線上自動生成工具 API 文件與 API 定義同步更新。
- 支援多種語言 如:Java 、PHP、Asp.net……
簡介
Swagger UI 允許任何人(無論您是開發團隊還是終端使用者)都可以視覺化 API 資源並與之互動,而無需任何實現邏輯。它是根據您的 OpenAPI(以前稱為 Swagger)規範自動生成的,具有視覺化文件,可簡化後端實現和客戶端使用。
特點
- 無依賴 UI 可以在任何開發環境中使用,無論是本地還是在 Web 端中。
- 人性化 允許最終開發人員輕鬆地進行互動,並嘗試 API 公開的每個操作,以方便使用。
- 易於瀏覽 歸類整齊的文件可快速查詢並使用資源和端點。
- 所有瀏覽器支援 Swagger UI 在所有主要瀏覽器中均可使用,以適應各種可能的情況。
- 完全可定製 通過完整的原始碼訪問方式以所需方式設定和調整 Swagger UI。
- 完整的 OAS 支援 視覺化 Swagger 2.0 或 OAS 3.0 中定義的 API。
SpringBoot 整合 Swagger
POM 檔案中匯入 springfox-swagger2 和 springfox-swagger-ui
<dependency> <groupId> io.springfox </groupId> <artifactId> springfox-swagger2 </artifactId> <version> 2.7.0 </version> </dependency> <dependency> <groupId> io.springfox </groupId> <artifactId> springfox-swagger-ui </artifactId> <version> 2.7.0 </version> </dependency>
- 配置 Swagger 編寫 SwaggerConfig 檔案
- 啟動類加註解@EnableSwagger2 開啟 Swagger2
- @ApiParam @ApiModelProperty
總結
Swagger UI有兩種風格,每個人使用習慣不同,根據具體喜好選擇自己中意的風格。
Yapi
簡介
YApi 是高效、易用、功能強大的 api 管理平臺,旨在為開發、產品、測試人員提供更優雅的介面管理服務。可以幫助開發者輕鬆建立、釋出、維護 API,YApi 還為使用者提供了優秀的互動體驗,開發人員只需利用平臺提供的介面資料寫入工具以及簡單的點選操作就可以實現介面的管理。
特點
- 基於 Json5 和 Mockjs 定義介面返回資料的結構和文件,效率提升多倍
- 扁平化許可權設計,即保證了大型企業級專案的管理,又保證了易用性
- 類似 postman 的介面除錯
- 自動化測試, 支援對 Response 斷言
- MockServer 除支援普通的隨機 mock 外,還增加了 Mock 期望功能,根據設定的請求過濾規則,返回期望資料
- 支援 postman, har, swagger 資料匯入
- 免費開源,內網部署,資訊再也不怕洩露了
教程
程式碼增量實現
通過自動識別 Swagger 地址解析成 Yapi 可識別的入參或者出參
- 當前問題
- 返回的資料是 AjaxResult 繼承了 HashMap<String, Object>,swagger 無法識別每個欄位的含義?
- yapi 可識別的資料格式是什麼?
- 解決
- 定義了返回型別 Result
- JSON-SCHEMA
JSON Schema
- 定義
JSON 是目前應用非常廣泛的資料交換格式。既然是用於資料交換的格式,那麼就存在資料交換的雙方。如何約定或校驗對方的資料格式是符合要求的,就成了服務互動需要解決的一個問題。所以 JSON Schema 就是用來定義 JSON 資料約束的一個標準。根據這個約定模式,交換資料的雙方可以理解 JSON 資料的要求和約束,也可以據此對資料進行驗證,保證資料交換的正確性。 - 版本
The current version is 2019-09! - 格式
{
" $schema" : "http://json-schema.org/draft-07/schema#",
"$ id" : "http://example.com/product.schema.json",
"description" : "A product from Acme's catalog",
"properties" : {
"dimensions" : {
"properties" : {
"height" : {
"type" : "number"
},
"length" : {
"type" : "number"
},
"width" : {
"type" : "number"
}
},
"required" : [ "length", "width", "height" ],
"type" : "object"
},
"price" : {
"description" : "The price of the product",
"exclusiveMinimum" : 0,
"type" : "number"
},
"productId" : {
"description" : "The unique identifier for a product",
"type" : "integer"
},
"productName" : {
"description" : "Name of the product",
"type" : "string"
},
"tags" : {
"description" : "Tags for the product",
"items" : {
"type" : "string"
},
"minItems" : 1,
"type" : "array",
"uniqueItems" : true
}
},
"required" : [ "productId", "productName", "price" ],
"title" : "Product",
"type" : "object"
}
-
分析說明:
" $schema": "http://json-schema.org/draft-07/schema#"
說明當前使用的schema版本,可以不包含
"$ id": "http://example.com/product.schema.json"
當前 schema 的唯一 id 標識,一般指向一個自主域名。方便後續引用,可以不包含
"title": "Product"
當前 schema 的標題,簡要描述資訊,可不包含
"description": "A product from Acme's catalog"
詳細描述資訊,可不包含
"type": "object"
約束物件是 object,也就是在 { } 中的資料
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
}object 中具體屬性的約束,description 是描述資訊,不產生具體約束。
type 約束 productid 屬性型別為整型
"productName": {
"description": "Name of the product",
"type": "string"
},約束 productName 屬性型別為字元型
"price": {
"description": "The price of the product",
"type": "number",
"exclusiveMinimum": 0
}約束 price 屬性型別為數字型,可以是整型或浮點型。
exclusiveMinimum 約束該數字 >0(不包含 0)
"tags": {
"description": "Tags for the product",
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}約束 tag 屬性是 array 陣列。items 是陣列項約束,這裡約束陣列項均為字元型
minItems 陣列至少包含 1 項。
uniqueItems 約束陣列中每項不得重複
{ "dimensions" : { "properties" : { "height" : { "type" : "number" }, "length" : { "type" : "number" }, "width" : { "type" : "number" } }, "required" : [ "length", "width", "height" ], "type" : "object" } }
約束 dimensions 巢狀物件,其中 length,width,height 均為數字型別
且這三個欄位在 dimensions 物件中必須包含
{ "required" : [ "productId", "productName", "price" ] }
當前資料物件必須包含 productId,productName,price 三個欄位
個人總結
Swagger bootstrap ui
- swagger-bootstrap-ui官網:https://doc.xiaominfo.com/
- Spring Boot匯入POM依賴
<!--swagger-api 依賴開始-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.2</version>
</dependency>
<!--swagger-api 依賴結束-->
總結
專案中採用swagger-ui作為自動生成文件工具非常方便,無需花費額外的時候維護介面文件,而swagger-bootstrap-ui更強大,可以線上生成.md格式介面文件,除了開發人員自己使用外,匯出作為專案交付物也非常方便,個人建議Spring Boot專案中使用swagger-bootstrap-ui作為介面文件工具是最佳方案,本人所在專案自從使用了該外掛後,再沒用過其他類似工具,得到團隊一致肯定,測試也經常採用該工具測試介面。
總之一句話,選擇swagger-bootstrap-ui就對了,你會愛上它的。