前言
在微服务架构中,随着服务数量的增加,API文档管理变得越来越复杂。每个微服务都有自己的Swagger文档,开发人员需要记住每个服务的文档地址,这无疑增加了开发难度。本文将介绍如何使用Spring Cloud Gateway聚合所有微服务的Swagger文档,实现一站式API文档管理。
步骤:1、导包;
2、配置两个Config3、启动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;
@Autowired
public 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;
@Override
public 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文档的管理效率和开发体验。