无法从 spring 云网关访问 api-微服务文档。无法加载 API 定义

Cannot access api-docs of microservice from spring cloud gateway. Failed to load API definition

我正在尝试 link 我的微服务到我的网关。 ,但我无法通过网关访问我的微服务的 api-docs。

来自 Swagger 的错误-UI:

Failed to load API definition
Fetch error
Not Found http://localhost:8080/microservice/v2/api-docs

Swagger 版本:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

我可以 GET api-docs 直接通过微服务(端口 8081):

http://localhost:8081/v2/api-docs

但我无法通过网关(端口 8080)执行此操作:

http://localhost:8080/microservice/v2/api-docs

微服务的属性:

spring:
  application:
    name: microservice

server:
  port: 5082
...

网关的属性:

server:
  port: 2443

spring:
  cloud:
    gateway:
      routes:
      - id: microservice
        uri: lb://microservice
        predicates:
        - Path=/microservice/**
...

我发现的解决方法是在我的 Controller.java 中添加一个 @GetMapping 以将 URL 专门指向 api-docs(但我很漂亮确保这不是正确的解决方案)。

WebClient webClient;

@ResponseBody
@GetMapping(value = "/v2/api-docs")
public String getApiDocs()
{
    factory = new DefaultUriBuilderFactory("http://localhost:8081");
    factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
    
    this.webClient = WebClient
              .builder()
              .uriBuilderFactory(factory)
              .build();

    return webClient.get()
        .uri("/v2/api-docs")
        .retrieve()
        .bodyToMono(String.class)
        .block();
}

仅供参考:

问题是网关未配置为加载 swagger 相关资源(UI,配置文件)。 我将在解释网关配置中使用 @Configuration class,但它可能也可以在属性文件中使用。

  1. 为每个服务指定自定义 Swagger API 路径。因此,它可以用于在接下来的步骤中在网关中配置路由。它将在 swagger UI URL 和 swagger JSON 配置文件的路径中添加前缀 /microservice1-api
springdoc:
      api-docs:
        path: /microservice1-api
      swagger-ui:
        path: /api.html
  1. 在网关配置中指定到每个前缀的路由。因此它将正确路由与服务 swagger 资源关联的路径。
    RouteLocatorBuilder.Builder apiDocJsonRoutes(RouteLocatorBuilder.Builder builder) {
    //uri can be actual URI or load balancer path
            return builder
                    .route(p -> p.path( "/microservice1-api/**").uri("microservice1"))
                    .route(p -> p.path( "/microservice2-api/**").uri("microservice2"))
                    .route(p -> p.path("/microservice3-api/**").uri("microservice3"));
        }
  1. 您必须为 /swagger-ui/index.html 定义正确服务路径的路由。在这种情况下,服务路径由 URL 参数 configUrl 识别。在第 1 步之后,如果您在浏览器中打开 swagger,您将看到在地址行的末尾有参数 ?configUrl=/microservice1-api/swagger-config。因此,如果此参数值具有与特定服务关联的前缀,则可以将其用于路由。
RouteLocatorBuilder.Builder apiDocUIRoutes(RouteLocatorBuilder.Builder builder) {
        return builder
                .route(p -> swaggerUi(p, "microservice1", "/microservice1-api/swagger-config"))
                .route(p -> swaggerUi(p, "microservice2", "/microservice2-api/swagger-config"))
                .route(p -> swaggerUi(p, "microservice3", "/microservice3-api/swagger-config"));
    }


    private Buildable<Route> swaggerUi(PredicateSpec p, String service, String expectedValue) {
        return p.path("/swagger-ui/index.html").and().query("configUrl", expectedValue)
                .uri(service);
    }
  1. 在浏览器中使用 http://gateway_path/ 打开 API microservice_route/api.html