作者 | 柯然(邪影)
來源|阿里巴巴雲原生公眾號
背景
Swagger 是一個規范和完整的前端框架,用於生成、描述、調用和可視化 RESTful 風格的 Web 服務。Swagger 規范也逐漸發展成為了 OpenAPI 規范。
Springfox 是一個集成了 Swagger,基於 Sring MVC/Spring Webflux 實現的一個 Swagger 描述文件生成框架,通過使用它定義的一些描述接口的注解自動生成 Swagger 的描述文件,使 Swagger 能夠展示並調用接口。
相信很多人都聽說和使用過 Swagger 和 Springfox,這里就不再贅述了。
Dubbo-Admin 中有接口測試功能,但是缺少接口描述的文檔,所以該測試功能比較適合接口開發人員用於測試接口。而其他人想要使用該功能就必須先通過接口開發者編寫的文檔或者其他方式,了解清楚接口信息才能使用該功能測試接口。
Dubbo 這邊有沒有集合文檔展示和測試功能,可以不用寫文檔就能把接口直接給調用方,類似 Swagger/Springfox 的工具呢?
之前做過一些調研,找到一些類似的工具:
- 有些是基於 Springfox 做的,直接一個文本域放 JSON,與目前 Admin 中的測試功能大同小異。
- 有些是直接基於 Swagger 的 Java 版 OpenApI 規范生成工具做的,能把一些基礎數據類型的簡單參數作為表單項展示。
它們都有一個共同點:會把你的提供者變為 Web 項目。當然有些提供者是通過 web 容器加載啟動的,甚至也有和 web 工程在一起的,那就無所謂了。
但也有非 web 的提供者,為了文檔我得把它變為 web 項目嗎?(還要引入一堆 Web 框架的依賴?比如 Spring MVC?)或者說生產環境打包時,刪除它的引用和代碼里的相關注解? 有沒有簡單點的方式呢?
OpenAPI 中沒有 RPC 的規范,Swagger 是 OpenAPI 的實現,所以也不支持 RPC 相關調用。Springfox 是通過 Swagger 實現的 RESTful API 的工具,而 RESTful 又是基於 Web 的,Dubbo 沒法直接使用。我們最終選擇了自己實現:
- 提供一些描述接口信息的簡單注解。
- 在提供者啟動時解析注解並緩存解析結果。
- 在提供者增加幾個 Dubbo-Api-Docs 使用的獲取接口信息的接口。
- 在 Dubbo Admin 側通過 Dubbo 泛化調用實現 Http 方式調用 Dubbo 接口的網關。
- 在 Dubbo Admin 側實現接口信息展示和調用接口功能。
- 下列情況中的參數直接展示為表單項,其他的展示為 JSON。
- 方法參數為基礎數據類型的
- 方法參數為一個 Bean,Bena 中屬性為基礎數據類型的
- 很少的第三方依賴,甚至大部分都是你項目里本身就使用的。
- 可以通過 profile 決定是否加載,打包時簡單地修改 profile 就能區分生產和測試,甚至 profile 你本來就使用了。
今天,我很高興的宣布:Dubbo 用戶也可以享受類似 Swagger 的體驗了 -- Dubbo-Api-Docs 發布了。
簡介
Dubbo-Api-Docs 是一個展示 dubbo 接口文檔,測試接口的工具。
使用 Dubbo-Api-Docs 分為兩個主要步驟:
-
在 dubbo 項目引入 Dubbo-Api-Docs 相關 jar 包,並增加類似 Swagger 的注解。
-
在 Dubbo-Admin 中查看接口描述並測試。
通過以上兩個步驟,即可享受類似 Swagger 的體驗,並且可以在生產環境中關閉 Dubbo-Api-Docs 的掃描。
Dubbo-Api-Docs 目前通過直連服務節點的方式獲取該服務的接口列表。測試接口時,可以直連也可以通過注冊中心,未來會增加通過注冊中心獲取服務列表的方式,並根據 Dubbo 的升級規划增加新的功能支持,也會根據社區的需求增加功能。
Dubbo-Api-Docs 會在服務提供者啟動完畢后,掃描 docs 相關注解並將處理結果緩存,並增加一些 Dubbo-Api-Docs 相關的 Dubbo 提供者接口。緩存的數據在將來可能會放到 Dubbo 元數據中心中。
當前版本: 2.7.8.1
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-api-docs-annotations</artifactId>
<version>${dubbo-version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-api-docs-core</artifactId>
<version>${dubbo-version}</version>
</dependency>
快速入門
1. dubbo 提供者項目的方法參數中加上 Dubbo-Api-Docs 注解
- 如果 dubbo 提供者的接口和方法參數在一個單獨的 jar 項目中,則在該項目中引入: dubbo-api-docs-annotations。
- dubbo 提供者項目引入 dubbo-api-docs-core。
- 在提供者項目的項目啟動類(標注了 @SpringBootApplication 的類),或者配制類(標注了 @Configuration 的類)中增加注解 @EnableDubboApiDocs,以啟用 Dubbo Api Docs 功能。
為避免增加生產環境中的資源占用,建議單獨創建一個配制類用於啟用 Dubbo-Api-Docs,並配合 @Profile("dev") 注解使用。>
當然,Dubbo-Api-Docs 僅在項目啟動時多消耗了點 CPU 資源,並使用了一點點內存用於緩存,將來會考慮將緩存中的內容放到元數據中心。
下面以 dubbo-api-docs-examples 項目中的部分服務接口為例:
git clone -b 2.7.x https://github.com/apache/dubbo-spi-extensions.git
進入 dubbo-spi-extensions/dubbo-api-docs/dubbo-api-docs-examples 目錄。
dubbo-api-docs-examples 中有兩個子模塊:
- examples-api:一個 jar 包項目,其中包含服務的接口和接口參數 Bean。
- examples-provider:提供者服務端,包含 spring boot 啟動器和服務的實現。
下面我們在這兩個子模塊中增加 Dubbo-Api-Docs:
examples-api:
maven 引入:
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-api-docs-annotations</artifactId>
<version>2.7.8</version>
</dependency>
org.apache.dubbo.apidocs.examples.params 中有兩個 Bean,我們來為它們添加 docs 注解。
- QuickStartRequestBean 作為參數 Bean,添加 @RequestParam。
public class QuickStartRequestBean {
@RequestParam(value = "You name", required = true, description = "please enter your full name", example = "Zhang San")
private String name;
@RequestParam(value = "You age", defaultValue = "18")
private int age;
@RequestParam("Are you a main?")
private boolean man;
// getter/setter略...
}
- QuickStartRespBean 作為響應 Bean,添加 @ResponseProperty。
public class QuickStartRespBean {
@ResponseProperty(value = "Response code", example = "500")
private int code;
@ResponseProperty("Response message")
private String msg;
// getter/setter略...
}
由於我們只挑選了部分接口作為演示,到此這些接口涉及的 docs 注解添加完畢。
examples-provider:
maven 引入:
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-api-docs-core</artifactId>
<version>2.7.8</version>
</dependency>
我們挑選一個接口作為演示:
org.apache.dubbo.apidocs.examples.api.impl.QuickStartDemoImpl 中的 quickStart 方法。
QuickStartDemoImpl 實現了 api 包中的 org.apache.dubbo.apidocs.examples.api.IQuickStartDemo 接口。
- 在 QuickStartDemoImpl 中:
@DubboService
@ApiModule(value = "quick start demo", apiInterface = IQuickStartDemo.class, version = "v0.1")
public class QuickStartDemoImpl implements IQuickStartDemo {
@ApiDoc(value = "quick start demo", version = "v0.1", description = "this api is a quick start demo", responseClassDescription="A quick start response bean")
@Override
public QuickStartRespBean quickStart(@RequestParam(value = "strParam", required = true) String strParam, QuickStartRequestBean beanParam) {
return new QuickStartRespBean(200, "hello " + beanParam.getName() + ", " + beanParam.toString());
}
}
到此 docs 相關注解已添加完畢,下面我們來開啟 Dubbo-Api-Docs。新增一個配制類,位置任意,只要能被 spring boot 掃描到就行。
我們在 org.apache.dubbo.apidocs.examples.cfg 包中新增一個配制類 DubboDocConfig:
@Configuration
@Profile("dev") // 配合 Profile 一起使用, 在 profile 為 dev 時才會加載該配制類
@EnableDubboApiDocs // 開啟 Dubbo-Api-Docs
public class DubboDocConfig {
}
到此 Dubbo-Api-Docs 相關的東西已經添加完畢。
dubbo-api-docs-examples 中有更多更為詳盡的例子,下文中有注解的詳細說明。下面我們來看一下增加 Dubbo-Api-Docs 后的效果圖:
2. 啟動提供者項目
- 示例使用 nacos 作為注冊中心,下載並啟動 nacos。
- 在上面的例子中,我們啟動 examples-provider 項目中的 org.apache.dubbo.apidocs.examples.ExampleApplication。
在 examples-provider 目錄中:
mvn spring-boot:run
3. 下載 dubbo-admin
dubbo-admin 倉庫
dubbo-admin 需要下載 develop 分支源碼啟動。
git clone -b develop https://github.com/apache/dubbo-admin.git
4. 啟動訪問 dubbo-admin
參考 dubbo-admin 里的說明啟動:
1. 在 dubbo-admin-server/src/main/resources/application.properties 中修改注冊中心地址
2. 編譯 mvn clean package
3. 啟動:
mvn --projects dubbo-admin-server spring-boot:run
或者
cd dubbo-admin-distribution/target; java -jar dubbo-admin-0.1.jar
4. 瀏覽器訪問: http://localhost:8080
5. 默認帳號密碼都是: root
5. 進入"接口文檔"模塊
- 在 “dubbo 提供者 IP” 和 “dubbo提供者端口” 中分別輸入提供者所在機器 IP 和端口,點擊右側 “加載接口列表” 按鈕。
- 左側接口列表中加載出接口列表,點擊任意接口,右邊展示出該接口信息及參數表單。
- 填入表單內容后,點擊最下方測試按鈕。
- 響應部分展示了響應示例及實際響應結果。
源碼倉庫
Dubbo-Api-Docs 根據功能拆分,分別在兩個倉庫中:
1. dubbo-spi-extensions
dubbo-spi-extensions 倉庫地址
該倉庫存放 dubbo 的一些非核心功能的擴展,Dubbo-Api-Docs 作為該倉庫中的一個子模塊,由於該倉庫屬於 Dubbo 3.0 中規划的一部分,而 Dubbo-Api-Docs 是基於 Dubbo 2.7.x 開發的,所以在該倉庫中增加了 2.7.x 分支,Dubbo-Api-Docs 就在該分支下。
該倉庫中包含了 Dubbo-Api-Docs 的文檔相關注解、注解掃描能力和使用示例:
- dubbo-api-docs-annotations:文檔生成的相關注解。考慮到實際情況中 dubbo api 的接口類和接口參數會規划為一個單獨的 jar 包,所以注解也獨立為一個 jar 包。本文后面會對注解做詳細說明。
- dubbo-api-docs-core:負責解析注解,生成文檔信息並緩存。前面提到的 Dubbo-Api-Docs 相關接口也在該包中。
- dubbo-api-docs-examples:使用示例。
2. Dubbo-Admin
Dubbo-Admin 倉庫地址
文檔的展示及測試放在了 dubbo admin 項目中。
注解說明
-
@EnableDubboApiDocs:配制注解,啟用 dubbo api docs 功能。
-
@ApiModule:類注解,dubbo 接口模塊信息,用於標注一個接口類模塊的用途。
- value:模塊名稱
- apiInterface:提供者實現的接口
- version:模塊版本
-
@ApiDoc:方法注解,dubbo 接口信息,用於標注一個接口的用途。
- value:接口名稱
- description:接口描述(可使用 html 標簽)
- version:接口版本
- responseClassDescription:響應的數據的描述
-
@RequestParam:類屬性/方法參數注解,標注請求參數。
- value:參數名
- required:是否必傳參數
- description:參數描述
- example:參數示例
- defaultValue:參數默認值
- allowableValues:允許的值,設置該屬性后界面上將對參數生成下拉列表
- 注:使用該屬性后將生成下拉選擇框
- boolean 類型的參數不用設置該屬性,將默認生成 true/false 的下拉列表
- 枚舉類型的參數會自動生成下拉列表,如果不想開放全部的枚舉值,可以單獨設置此屬性
-
@ResponseProperty:類屬性注解,標注響應參數。
- value:參數名
- example:示例
使用注意
- 響應 bean(接口的返回類型)支持自定義泛型,但只支持一個泛型占位符。
- 關於 Map 的使用:Map 的 key 只能用基本數據類型。如果 Map 的 key 不是基礎數據類型,生成的就不是標准 json 格式,會出異常。
- 接口的同步/異步取自 org.apache.dubbo.config.annotation.Service#async / org.apache.dubbo.config.annotation.DubboService#async。
示例說明
dubbo-spi-extensions / Dubbo-Api-Docs 中的 dubbo-api-docs-examples 目錄中為示例工程:
- examples-api:jar 包項目,包含服務提供者的接口類及參數 Bean。
- examples-provider:使用 dubbo-spring-boot-starter 的提供者項目,注冊中心使用 nacos。
- examples-provider-sca:使用 spring-cloud-starter-dubbo 的提供者項目,注冊中心使用 nacos。
示例使用步驟
-
示例使用 nacos 作為注冊中心,下載並啟動 nacos。
-
任意啟動 examples-provider 和 examples-provider-sca 中的任意一個,當然也可以兩個都啟動。examples-provider 使用 20881 端口 examples-provider-sca 使用 20882 端口。兩個項目都是 spring boot 項目,啟動類在 org.apache.dubbo.apidocs.examples 包下。
-
啟動 Dubbo-Admin,瀏覽器訪問:http://localhost:8080。
-
進入 dubbo-admin 中的 “接口文檔” 模塊。
-
在 “dubbo 提供者 IP” 和 “dubbo 提供者端口” 中分別輸入提供者所在機器 IP 和端口,點擊右側 “加載接口列表” 按鈕。
-
左側接口列表中加載出接口列表,點擊任意接口,右邊展示出該接口信息及參數表單。
-
填入表單內容后,點擊最下方測試按鈕。
-
響應部分展示了響應示例及實際響應結果。
如果你對 Dubbo Api Docs 的建設有興趣,歡迎你釘釘搜索群號:34403965,加入 Dubbo Api Docs 共建小組;也歡迎你釘釘搜索群號:21976540,加入 Dubbo 開源討論群。