在微服务架构下,如果给每个微服务都配置文档,那么每个微服务的接口文档都有自己独立的访问地址,这样要一个个打开每个微服务的文档非常麻烦。一般我们会采用聚合的办法,将所有微服务的接口整合到一个文档中,具体做法有2种:
- 第1种:采用Knife4j官方提供的knife4j-aggregation-spring-boot-starter,
- 第2种:在网关中手动配置聚合。
使用knife4j-aggregation-spring-boot-starter
1)新建聚合文档的微服务doc-service,并添加依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-aggregation-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
2)做如下配置:
spring:
application:
name: doc-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
knife4j:
enableAggregation: true
nacos:
enable: true # 开启Nacos模式
serviceUrl: http://localhost:8848/nacos # Nacos注册中心地址
routes:
- name: 用户服务nacos #微服务在聚合文档中的名称
serviceName: user-service # 微服务的服务名
location: /v2/api-docs # 微服务文档资源路径
- name: 订单服务nacos
serviceName: order-service
location: /v2/api-docs
# cloud:
# enable: true
# routes:
# - name: 用户服务cloud #微服务在聚合文档中的名称
# uri: localhost:8082 # 微服务的http地址
# location: /v2/api-docs # 微服务文档资源路径
# - name: 订单服务cloud
# uri: localhost:8081
# location: /v2/api-docs
3)测试
浏览器访问http://localhost:8888/doc.html即可切换查看不同微服务的接口文档:
手动配置Gateway聚合
1)网关添加knife4j依赖
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
2)网关中添加获取swagger分组的接口
@RestController
public class SwaggerHandler {
private final SwaggerResourcesProvider swaggerResources;
@Autowired
public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
this.swaggerResources = swaggerResources;
}
/**
* Swagger资源配置,微服务中这各个服务的api-docs信息
*/
@GetMapping("/swagger-resources")
public Mono<ResponseEntity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}
}
/**
* Swagger资源配置
*/
@Slf4j
@Component
@Primary
@RequiredArgsConstructor
public class SwaggerResourceConfig implements SwaggerResourcesProvider {
private final RouteLocator routeLocator;
/**
* swagger2默认的url后缀
*/
private static final String SWAGGER2_URL = "/v2/api-docs";
/**
* 网关应用名称
*/
@Value("${spring.application.name}")
private String gatewayName;
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
Map<String, String> servers = new HashMap<>();
// 1.获取路由 Uri中的 Host 作为服务名,把路由id作为请求路径,这里要确保路由id与路由path前缀一致
routeLocator.getRoutes()
.filter(route -> route.getUri().getHost() != null)
.filter(route -> !gatewayName.equals(route.getUri().getHost()))
.subscribe( r -> servers.put(r.getUri().getHost(), r.getId()));
// 2.创建自定义资源
servers.forEach((name, path) -> {
// 创建Swagger 资源
SwaggerResource swaggerResource = new SwaggerResource();
// 设置访问地址
swaggerResource.setUrl("/" + path + SWAGGER2_URL);
// 设置名称
swaggerResource.setName(name);
swaggerResource.setSwaggerVersion("3.0.0");
resources.add(swaggerResource);
});
return resources;
}
}
3)网关中正常配置路由转发规则
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes: #配置路由路径
- id: user-service
uri: lb://user-service
predicates:
- Path=/user-service/**
filters:
- StripPrefix=1
- id: order-service
uri: lb://order-service
predicates:
- Path=/order-service/**
filters:
- StripPrefix=1
4)测试
浏览器访问localhost:8080/doc.html,即可切换查看不同微服务的接口文档:
总结
2种方式都可以实现文档聚合的效果,显然网关中手动做聚合会更方便,因为不需要额外启动一个专门做文档聚合的微服务。完整的源码下载:聚合文档https://github.com/xjs1919/enumdemo/tree/master/gateway-knife4j