前言
在微服務架構中,隨著服務數量的增加,API文檔管理變得越來越復雜。每個微服務都有自己的Swagger文檔,開發人員需要記住每個服務的文檔地址,這無疑增加了開發難度。本文將介紹如何使用Spring Cloud Gateway聚合所有微服務的Swagger文檔,實現一站式API文檔管理。
步驟:1、導包;
? ? ? ? ? ?2、配置兩個Config? ? ? ? ? ?3、啟動gateway,選擇服務訪問
為什么需要聚合Swagger文檔?
-
統一入口:所有API文檔通過網關統一訪問
-
簡化開發:開發人員無需記憶多個文檔地址
-
權限控制:可在網關層統一控制文檔訪問權限
-
提升效率:減少服務間切換的時間成本
實現步驟
1. 添加依賴
首先在Gateway服務的pom.xml中添加Swagger相關依賴:
<!-- Swagger2核心依賴 -->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version>
</dependency><!-- Swagger UI界面依賴 -->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version>
</dependency>
2. 配置Swagger資源處理器
創建SwaggerHandler類處理Swagger相關請求:
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler {@Autowired(required = false)private SecurityConfiguration securityConfiguration;@Autowired(required = false)private UiConfiguration uiConfiguration;private final SwaggerResourcesProvider swaggerResources;@Autowiredpublic SwaggerHandler(SwaggerResourcesProvider swaggerResources) {this.swaggerResources = swaggerResources;}@GetMapping("/configuration/security")public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {return Mono.just(new ResponseEntity<>(Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));}@GetMapping("/configuration/ui")public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {return Mono.just(new ResponseEntity<>(Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));}@GetMapping("")public Mono<ResponseEntity> swaggerResources() {return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));}
}
3. 配置Swagger資源提供者
創建SwaggerProvider類,動態獲取所有微服務的Swagger文檔:
@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {public static final String API_URI = "/v2/api-docs";private final RouteLocator routeLocator;private final GatewayProperties gatewayProperties;@Overridepublic List<SwaggerResource> get() {List<SwaggerResource> resources = new ArrayList<>();List<String> routes = new ArrayList<>();routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(routeDefinition -> routeDefinition.getPredicates().stream().filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName())).forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", API_URI)))));return resources;}private SwaggerResource swaggerResource(String name, String location) {SwaggerResource swaggerResource = new SwaggerResource();swaggerResource.setName(name);swaggerResource.setLocation(location);swaggerResource.setSwaggerVersion("2.0");return swaggerResource;}
}
4. 測試訪問
完成配置后,訪問網關的Swagger UI界面:
http://gateway-address:port/swagger-ui.html
如圖我的是10010端口。
實現原理
-
動態發現:通過RouteLocator獲取所有注冊的路由信息
-
資源轉換:將路由信息轉換為Swagger資源
-
統一展示:Swagger UI通過網關聚合展示所有微服務的API文檔
常見問題解決
1. Swagger頁面無法加載
解決方案:
-
檢查網關是否正確配置了跨域支持
-
確保各微服務的Swagger文檔地址可訪問
-
驗證網關路由配置是否正確
2. 部分服務文檔不顯示
排查步驟:
-
檢查該服務是否正常注冊
-
驗證服務自身的Swagger文檔是否可訪問
-
檢查網關路由規則是否包含該服務
3. 權限控制
可通過網關統一控制Swagger文檔的訪問權限:
@Bean
public SecurityWebFilterChain swaggerSecurityFilterChain(ServerHttpSecurity http) {return http.authorizeExchange().pathMatchers("/swagger-ui.html", "/swagger-resources/**", "/v2/api-docs").authenticated().anyExchange().permitAll().and().httpBasic().and().build();
}
性能優化建議
-
緩存機制:對Swagger資源進行緩存,減少重復請求
-
按需加載:實現文檔的懶加載機制
-
版本管理:支持不同版本的API文檔展示
總結
通過Spring Cloud Gateway聚合Swagger文檔,我們實現了:
-
所有微服務API文檔的統一管理
-
動態發現和展示新增服務的API文檔
-
統一的權限控制和訪問入口
-
提升開發效率和協作體驗
這種方案特別適合中大型微服務項目,能顯著提高API文檔的管理效率和開發體驗。