「初學者商城」- 接口 - 聚合 Swagger(優化)

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

v1.4.2 下載地址:ziptar.gz

注:對於標籤的說明「初學者商城」- 寫在最前面 #5.1


3. 接口


注:查看更改內容:聚合 Swagger

3.1 聚合的思路

訪問每一個服務工程的/swagger-resources接口(http://localhost:8080/swagger-resourceshttp://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資源信息集合中,哪些需要:有接口的服務工程,如基礎工程日誌工程;那麼其他的工程就需要過濾掉。

怎麼過濾?

  1. 在需要過濾的工程的配置文件中,修改應用名稱爲統一格式
  application:
      # 應用名稱
      name: base-service-core

---

  application:
      # 應用名稱
      name: log-service-core		
  1. 在遍歷添加路由的時候做判斷
    /**
     * 特定服務名稱後綴
     */
    public static final String SERVICE_SUFFIX = "core";

	...
	
	.filter(route -> route.getUri().getHost().indexOf(SERVICE_SUFFIX.toUpperCase()) != -1)

3.4 其它

  1. 由於網關沒有引入公用工程(公用工程中配置了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>
  1. 版本號的升級

4. 驗證


4.1 接口

  1. 下載v1.4.2標籤的代碼或者對照本篇博客更改v1.4.1標籤的代碼
  2. 項目啓動後,訪問地址 http://localhost:8000/swagger-ui.html
  3. 在頁面右上角Select a spec處可以切換不同工程的接口文檔

5. 結語


如果是專門開發接口供他人調用,我覺得集成Swagger還是非常有必要的,如我手裏正在做的一個項目,專門爲客戶提供他們系統的接口,還又是pc又是app,有時候同樣的接口還得整理幾套接口文檔;而且接口不是一次能寫好的,需求的變更等原因導致接口改了,那麼接口文檔也要更上…這是非常浪費時間的!

如果集成了Swagger,代碼寫好發佈後,就可以直接獲取到最新的接口文檔了:

“代碼即接口文檔,接口文檔即代碼”,巴適。


希望能夠幫助到你

over




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章