别再手动拼URL了!SpringCloud Gateway + Swagger3 一站式聚合所有微服务API文档(附完整配置代码)

张开发
2026/5/10 10:08:13 15 分钟阅读

分享文章

别再手动拼URL了!SpringCloud Gateway + Swagger3 一站式聚合所有微服务API文档(附完整配置代码)
Spring Cloud Gateway Swagger3 微服务API文档聚合实战指南在微服务架构中API文档的分散管理一直是开发者面临的痛点。想象一下当你的系统包含十几个微服务时为了查看不同服务的接口文档不得不记住每个服务的端口号和访问路径这种体验简直让人抓狂。本文将带你用Spring Cloud Gateway和Swagger3打造一套优雅的文档聚合方案告别手动拼接URL的原始操作。1. 为什么选择Spring Cloud Gateway Swagger3组合传统Zuul网关在文档聚合方面存在诸多限制而Spring Cloud Gateway作为新一代网关提供了更强大的路由能力和性能表现。结合Swagger3的最新特性我们可以构建一个现代化的文档中心。核心优势对比特性Zuul Swagger2Spring Cloud Gateway Swagger3性能基于Servlet阻塞模型基于Netty非阻塞模型文档聚合灵活性需要手动配置每个服务支持动态路由自动发现OpenAPI支持仅支持Swagger2原生支持OpenAPI 3.0规范配置复杂度高需要维护大量路由规则低支持服务注册中心自动发现文档界面传统Swagger UI可选新版Swagger UI或ReDoc提示Spring Cloud Gateway的底层基于WebFlux对于响应式应用有更好的支持吞吐量比Zuul高约50%2. 基础环境搭建2.1 项目依赖配置首先确保你的父pom中包含必要的依赖管理dependencyManagement dependencies dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-dependencies/artifactId version2021.0.3/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement各微服务模块需要添加Swagger3依赖dependency groupIdio.springfox/groupId artifactIdspringfox-boot-starter/artifactId version3.0.0/version /dependency网关模块需要额外添加dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-starter-gateway/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency2.2 基础配置示例每个微服务的Swagger配置类可以这样编写Configuration EnableOpenApi public class SwaggerConfig { Bean public Docket api() { return new Docket(DocumentationType.OAS_30) .select() .apis(RequestHandlerSelectors.basePackage(com.your.package)) .paths(PathSelectors.any()) .build() .apiInfo(apiInfo()); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title(订单服务API文档) .description(订单微服务接口说明) .version(1.0) .build(); } }3. 网关层文档聚合实现3.1 动态路由配置在application.yml中配置网关路由规则spring: cloud: gateway: discovery: locator: enabled: true lower-case-service-id: true routes: - id: order-service uri: lb://order-service predicates: - Path/api/order/** filters: - StripPrefix1 - id: product-service uri: lb://product-service predicates: - Path/api/product/** filters: - StripPrefix13.2 文档聚合核心逻辑创建Swagger资源提供者Component Primary public class SwaggerProvider implements SwaggerResourcesProvider { private final RouteLocator routeLocator; private final GatewayProperties gatewayProperties; public SwaggerProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) { this.routeLocator routeLocator; this.gatewayProperties gatewayProperties; } Override public ListSwaggerResource get() { ListSwaggerResource resources new ArrayList(); ListString routes new ArrayList(); // 获取所有路由ID routeLocator.getRoutes().subscribe(route - routes.add(route.getId())); // 根据路由配置生成文档资源 gatewayProperties.getRoutes().stream() .filter(route - routes.contains(route.getId())) .forEach(route - { String name route.getId(); String location / name /v3/api-docs; resources.add(swaggerResource(name, location)); }); return resources; } private SwaggerResource swaggerResource(String name, String location) { SwaggerResource swaggerResource new SwaggerResource(); swaggerResource.setName(name); swaggerResource.setLocation(location); swaggerResource.setSwaggerVersion(3.0); return swaggerResource; } }3.3 自定义文档控制器RestController RequestMapping(/swagger-resources) public class SwaggerController { private final SwaggerResourcesProvider swaggerResources; public SwaggerController(SwaggerResourcesProvider swaggerResources) { this.swaggerResources swaggerResources; } GetMapping public ResponseEntityListSwaggerResource swaggerResources() { return ResponseEntity.ok(swaggerResources.get()); } }4. 高级配置与优化技巧4.1 安全控制配置为了保护API文档我们可以添加简单的安全验证Bean public SecurityWebFilterChain swaggerSecurity(ServerHttpSecurity http) { return http .authorizeExchange() .pathMatchers(/swagger-ui/**, /v3/api-docs/**).authenticated() .anyExchange().permitAll() .and() .httpBasic() .and() .csrf().disable() .build(); }在application.yml中添加认证信息spring: security: user: name: admin password: doc1234.2 文档分组优化对于大型系统建议按业务域进行文档分组// 在网关的Swagger配置中添加 Bean public GroupedOpenApi usersGroup() { return GroupedOpenApi.builder() .group(用户中心) .pathsToMatch(/api/user/**) .build(); } Bean public GroupedOpenApi orderGroup() { return GroupedOpenApi.builder() .group(订单中心) .pathsToMatch(/api/order/**) .build(); }4.3 响应缓存优化为提升文档加载性能可以添加缓存控制Bean public WebFilter swaggerCacheFilter() { return (exchange, chain) - { ServerHttpRequest request exchange.getRequest(); if (request.getURI().getPath().contains(swagger) || request.getURI().getPath().contains(api-docs)) { ServerHttpResponse response exchange.getResponse(); response.getHeaders().setCacheControl(max-age3600); } return chain.filter(exchange); }; }5. 生产环境最佳实践5.1 文档访问路径定制默认的Swagger UI路径可能不符合企业规范可以通过配置自定义springfox: documentation: swagger-ui: base-url: /api-docs path: /developer-portal5.2 环境隔离策略不同环境应使用不同的文档策略Profile(!prod) Configuration EnableOpenApi public class DevSwaggerConfig { // 开发环境完整配置 } Profile(prod) Configuration public class ProdSwaggerConfig { // 生产环境精简配置 Bean public Docket api() { return new Docket(DocumentationType.OAS_30) .enable(false) // 生产环境禁用文档 .select() .apis(RequestHandlerSelectors.none()) .paths(PathSelectors.none()) .build(); } }5.3 监控与告警添加健康检查端点监控文档服务状态Bean public HealthIndicator swaggerHealthIndicator() { return () - { try { // 检查文档服务可用性 return Health.up().build(); } catch (Exception e) { return Health.down(e).build(); } }; }在Spring Boot Admin或Prometheus中配置告警规则当文档服务不可用时及时通知开发团队。

更多文章