在微服务架构下,如果给每个微服务都配置文档,那么每个微服务的接口文档都有自己独立的访问地址,这样要一个个打开每个微服务的文档非常麻烦。一般我们会采用聚合的办法,将所有微服务的接口整合到一个文档中,具体做法有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-servicecloud:nacos:discovery:server-addr: localhost:8848
knife4j:enableAggregation: truenacos:enable: true # 开启Nacos模式serviceUrl: http://localhost:8848/nacos # Nacos注册中心地址routes:- name: 用户服务nacos #微服务在聚合文档中的名称serviceName: user-service # 微服务的服务名location: /v2/api-docs # 微服务文档资源路径- name: 订单服务nacosserviceName: order-servicelocation: /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;@Autowiredpublic 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;@Overridepublic 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: gatewaycloud:nacos:discovery:server-addr: localhost:8848gateway:routes: #配置路由路径- id: user-serviceuri: lb://user-servicepredicates:- Path=/user-service/**filters:- StripPrefix=1- id: order-serviceuri: lb://order-servicepredicates:- Path=/order-service/**filters:- StripPrefix=1
4)测试
浏览器访问localhost:8080/doc.html,即可切换查看不同微服务的接口文档:
总结
2种方式都可以实现文档聚合的效果,显然网关中手动做聚合会更方便,因为不需要额外启动一个专门做文档聚合的微服务。完整的源码下载:聚合文档https://github.com/xjs1919/enumdemo/tree/master/gateway-knife4j