SpringCloud-Knife4j文档聚合

在微服务架构下,如果给每个微服务都配置文档,那么每个微服务的接口文档都有自己独立的访问地址,这样要一个个打开每个微服务的文档非常麻烦。一般我们会采用聚合的办法,将所有微服务的接口整合到一个文档中,具体做法有2种:

  • 第1种:采用Knife4j官方提供的knife4j-aggregation-spring-boot-starter,
  • 第2种:在网关中手动配置聚合。

使用knife4j-aggregation-spring-boot-starter

1)新建聚合文档的微服务doc-service,并添加依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>com.github.xiaoymingroupId>
        <artifactId>knife4j-aggregation-spring-boot-starterartifactId>
    dependency>
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    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即可切换查看不同微服务的接口文档:
SpringCloud-Knife4j文档聚合_第1张图片

手动配置Gateway聚合

1)网关添加knife4j依赖

<dependencies>
     <dependency>
         <groupId>com.alibaba.cloudgroupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
     dependency>
     <dependency>
         <groupId>org.springframework.cloudgroupId>
         <artifactId>spring-cloud-starter-gatewayartifactId>
     dependency>
     <dependency>
         <groupId>com.github.xiaoymingroupId>
         <artifactId>knife4j-spring-boot-starterartifactId>
     dependency>
     <dependency>
         <groupId>org.springframework.cloudgroupId>
         <artifactId>spring-cloud-starter-loadbalancerartifactId>
     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,即可切换查看不同微服务的接口文档:
SpringCloud-Knife4j文档聚合_第2张图片

总结

2种方式都可以实现文档聚合的效果,显然网关中手动做聚合会更方便,因为不需要额外启动一个专门做文档聚合的微服务。完整的源码下载:聚合文档https://github.com/xjs1919/enumdemo/tree/master/gateway-knife4j

你可能感兴趣的:(spring,cloud,spring,后端)