SpringCloudGateway整合Swagger2聚合微服务系统API文档

头像
码农笔录
2019-06-12阅读 614

最近项目框架使用的是springcloud微服务,但是整合swagger的时候就懵了,因为springfox-swagger不支持webflux,gateway是webflux,而且你的微服务多了,没有一个总的入口也不行,所以给大家个方案。

springcloud版本是Greenwich.SR1,springboot版本是2.1.4

一.首先给各个微服务配置swagger

1.添加swagger的依赖,我这里用的是gradle,maven项目自行查找

implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'

2.配置swagger

@Configuration
@EnableSwagger2
public class SwaggerConfig {
//是否开启swagger,正式环境一般是需要关闭的,可根据springboot的多环境配置进行设置
@Value(value = "${swagger.enabled}")
Boolean swaggerEnabled;

@Bean
public Docket createRestApi() {
//给header添加参数token
ParameterBuilder tokenPar = new ParameterBuilder();
List<Parameter> pars = new ArrayList<Parameter>();
tokenPar.name("token").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
pars.add(tokenPar.build());
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(new ApiInfoBuilder()
.title("实景地球Swagger2 接口列表")
.description("地图、矢量数据相关")
.contact(new Contact("nelson", "http://www.globescene.cn", "mail_yanpeng@163.com"))
.version("1.0.0").build()
)
// 是否开启
.enable(swaggerEnabled).select()
// 扫描的路径包
.apis(RequestHandlerSelectors.basePackage("com.trgis.livearth.controller"))
// 指定路径处理PathSelectors.any()代表所有的路径
.paths(PathSelectors.any())
.build()
.globalOperationParameters(pars);
}
}


二、配置gateway

3.gateway增加同样依赖

implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'

4.配置SwaggerProvider,获取Api-doc,即SwaggerResources

@Component
@Primary
public class SwaggerProvider implements SwaggerResourcesProvider {
public static final String API_URI = "/v2/api-docs";
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;

public SwaggerProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
this.routeLocator = routeLocator;
this.gatewayProperties = gatewayProperties;
}

@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
//取出gateway的route
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
//结合配置的route-路径(Path),和route过滤,只获取有效的route节点
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;
}
}

因为Gateway里没有配置SwaggerConfig,而运行Swagger-ui又需要依赖一些接口,所以我的想法是自己建立相应的swagger-resource端点。  

@RestController
@RequestMapping("/swagger-resources")
public class SwaggerController {
@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)));
}
}

下面是最后的效果,gateway的端口是8800,在右边可以选择所有的微服务的swagger文档列表