I'm trying to link my microservices to my gateway. , but I'm not able to access the api-docs of my microservice through the gateway.
Error from Swagger-UI:
Failed to load API definition
Fetch error
Not Found http://localhost:8080/microservice/v2/api-docs
Swagger version:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
I can GET
the api-docs through the the microservice directly (port 8081):
http://localhost:8081/v2/api-docs
But I'm not able to do it through the gateway (port 8080):
http://localhost:8080/microservice/v2/api-docs
Microservice's properties:
spring:
application:
name: microservice
server:
port: 5082
...
Gateway's properties:
server:
port: 2443
spring:
cloud:
gateway:
routes:
- id: microservice
uri: lb://microservice
predicates:
- Path=/microservice/**
...
The workaround that I've found is to add a @GetMapping
in my Controller.java
to point the URL specifically to the api-docs
(but I'm pretty sure this is not the proper solution).
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();
}
FYI:
api-docs
of the gateway just fine, but not the api-docs
of the microservice.The issue is that the gateway is not configured to load swagger associated resources (UI, config files). I will use in the explanation gateway config using @Configuration class, but probably it can be used in the properties file as well.
springdoc:
api-docs:
path: /microservice1-api
swagger-ui:
path: /api.html
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"));
}
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);
}