1. 前言
在「初學者商城」- 搭建基礎架構(接口)# 7.3.1 Swagger 處有提到後續要聚合顯示Swagger
,這裏終於得到了實現。
爲什麼要聚合顯示?
- 目前是每個工程都有一個
/swagger-ui.html
的入口,就導致:- 很麻煩,每一個服務工程都要記住對應的地址和端口號
- 不安全,鑑權等操作都寫在網關;並且在部署的時候也不會對外暴露內部服務工程的端口
- 不完整,從中間某一環直接請求可能導致出現髒數據
達到的效果
- 只需訪問網關的
/swagger-ui.html
頁面,就能切換到不同服務工程的接口文檔
2. 源碼
完整項目地址:https://github.com/intomylife/osc-api
v1.4.2 標籤地址:https://github.com/intomylife/osc-api/releases/tag/v1.4.2
注:對於標籤的說明「初學者商城」- 寫在最前面 #5.1
3. 接口
注:查看更改內容:聚合 Swagger
3.1 聚合的思路
訪問每一個服務工程的/swagger-resources
接口(http://localhost:8080/swagger-resources,http://localhost:8081/swagger-resources),發現返回的信息都是[{"name":"default","url":"/v2/api-docs","swaggerVersion":"2.0","location":"/v2/api-docs"}]
這是一個什麼接口:用來獲取Swagger
的資源信息
我們跟着返回信息中的url
地址走一個,新開頁面訪問 http://localhost:8080/v2/api-docs,發現返回的是基礎工程中所有接口的描述信息(json 格式)
所以在網關中把基礎工程和日誌工程的/swagger-resources
資源信息整合在一起後,是否就能達到想要的效果呢。答案是肯定的,Swagger
也是支持這種解決方案
3.2 重寫核心接口
在網關中新增一個供訪問的前端控制器SwaggerResourceController
類
/**
* @ClassName SwaggerResourceController
* @Desc TODO 重寫核心接口
* @Date 2020/1/26 6:38 PM
* @Version 1.0
*/
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerResourceController {
private MySwaggerResourceProvider swaggerResourceProvider;
@Autowired
public SwaggerResourceController(MySwaggerResourceProvider swaggerResourceProvider) {
this.swaggerResourceProvider = swaggerResourceProvider;
}
@RequestMapping(value = "/configuration/security")
public ResponseEntity<SecurityConfiguration> securityConfiguration() {
return new ResponseEntity<>(SecurityConfigurationBuilder.builder().build(), HttpStatus.OK);
}
@RequestMapping(value = "/configuration/ui")
public ResponseEntity<UiConfiguration> uiConfiguration() {
return new ResponseEntity<>(UiConfigurationBuilder.builder().build(), HttpStatus.OK);
}
@RequestMapping
public ResponseEntity<List<SwaggerResource>> swaggerResources() {
return new ResponseEntity<>(swaggerResourceProvider.get(), HttpStatus.OK);
}
}
- 此時對應的正是每個服務工程訪問資源信息的
/swagger-resources
接口地址 - 重點就是要在
swaggerResources()
方法中把所有需要的服務工程的資源信息返回出來;可以看出,這個方法的返回類型裏面剛好可以放入List
集合
3.3 獲取服務工程的資源信息
3.3.1 SwaggerResource
SwaggerResource
資源信息對象,裏面需要服務工程的地址和名稱兩個屬性;在網關中,可以輕易的獲取到所有工程的路由信息,所以這個時候要做的就是,遍歷所有路由,把每個路由的地址和名稱封裝到SwaggerResource
對象中,並添加到集合,最後返回出去
3.3.2 過濾
然後並不是所有的工程都需要添加到Swagger
資源信息集合中,哪些需要:有接口的服務工程,如基礎工程和日誌工程;那麼其他的工程就需要過濾掉。
怎麼過濾?
- 在需要過濾的工程的配置文件中,修改應用名稱爲統一格式
application:
# 應用名稱
name: base-service-core
---
application:
# 應用名稱
name: log-service-core
- 在遍歷添加路由的時候做判斷
/**
* 特定服務名稱後綴
*/
public static final String SERVICE_SUFFIX = "core";
...
.filter(route -> route.getUri().getHost().indexOf(SERVICE_SUFFIX.toUpperCase()) != -1)
3.4 其它
- 由於網關沒有引入公用工程(公用工程中配置了
Swagger
的依賴),所以還需要在網關中引入springfox-swagger2
依賴
<springfox.version>2.9.2</springfox.version>
...
<!-- swagger 依賴 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox.version}</version>
</dependency>
- 版本號的升級
4. 驗證
4.1 接口
- 下載
v1.4.2
標籤的代碼或者對照本篇博客更改v1.4.1
標籤的代碼 - 項目啓動後,訪問地址 http://localhost:8000/swagger-ui.html
- 在頁面右上角
Select a spec
處可以切換不同工程的接口文檔
5. 結語
如果是專門開發接口供他人調用,我覺得集成Swagger
還是非常有必要的,如我手裏正在做的一個項目,專門爲客戶提供他們系統的接口,還又是pc
又是app
,有時候同樣的接口還得整理幾套接口文檔;而且接口不是一次能寫好的,需求的變更等原因導致接口改了,那麼接口文檔也要更上…這是非常浪費時間的!
如果集成了Swagger
,代碼寫好發佈後,就可以直接獲取到最新的接口文檔了:
“代碼即接口文檔,接口文檔即代碼”,巴適。
希望能夠幫助到你
over