springfox
springfox copied to clipboard
Aggregate API Docs in Spring Gateway failed
Please take the time to search the repository, if your question has already been asked or answered.
- [x] What version of the library are you using? 3.0.0
What kind of issue is this?
- [x] Bug report. If you’ve found a bug, spend the time to write a failing test.
The reproducer codes: https://github.com/hantsy/spring-puzzles/blob/master/springfox-gateway/
I tried to add an aggregated Swagger UI for all downstream service in a Microservices architecture, but failed.
@Primary
@Bean
public SwaggerResourcesProvider swaggerResourcesProvider(InMemorySwaggerResourcesProvider defaultResourcesProvider) {
return () -> {
SwaggerResource customersResource = new SwaggerResource();
customersResource.setName("Customers Endpoints");
customersResource.setSwaggerVersion("3.0");
customersResource.setUrl("/customers/v3/api-docs");
//customersResource.setUrl("http://localhost:8001/v3/api-docs");
SwaggerResource ordersResource = new SwaggerResource();
ordersResource.setName("Orders Endpoints");
ordersResource.setSwaggerVersion("3.0");
ordersResource.setUrl("/orders/v3/api-docs");
//ordersResource.setUrl("http://localhost:8002/v3/api-docs");
List<SwaggerResource> resources = new ArrayList<>(defaultResourcesProvider.get());
resources.add(customersResource);
resources.add(ordersResource);
return resources;
};
}
The router config in the gateway application.yml is similar to this.
spring:
cloud:
gateway:
routes:
- id: customers
uri: http://localhost:8001
predicates:
- Path=/customers/**
filters:
- RewritePath=/customers/(?<segment>.*), /$\{segment}
- id: orders
uri: http://localhost:8002
predicates:
- Path=/orders/**
filters:
- RewritePath=/orders/(?<segment>.*), /$\{segment}
The swagger resources url added the gateway URL by default, I can not set a full URL with HTTP/HTTPS protocol.
When running the application, the Swagger UI is displayed, but when I tried to run the endpoints in the downstream service(eg. hosted on http://localhost:8001), it always called on the gateway host(hosted on http://localhost:8080), it is incorrect.
Excepted: If it called on http://localhost:8080/customers, it will work due to rewrite rules, but it seems there is no way to set up the rewrite rules. Or called on the target host address: http://localhost:8001.
Hope there is a baseUrl. When it is set, the API Docs can be discovered via $baseUrl +"/v3/api-docs", and API endpoints test can be executed on the baseUrl directly.
So we can set the baseUrl to the gateway customers endpoints(http://localhost:8080/customers) instead of the target service.
Hope there is a baseUrl. When it is set, the API Docs can be discovered via $baseUrl +"/v3/api-docs", and API endpoints test can be executed on the baseUrl directly.
So we can set the baseUrl to the gateway customers endpoints(http://localhost:8080/customers) instead of the target service.
@hantsy I think my blog would help you about it.
https://blog.yuebaix.com/2021/10/04/%E4%B8%83%E5%A4%A9%E6%9E%84%E5%BB%BAspringcloud%E9%9B%86%E7%BE%A4/
I suppose the maintainer has not maintained for a long time.
This is the key solution.
@Primary
@Configuration
public class GatewayRoutesOasSwaggerResourcesProvider extends InMemorySwaggerResourcesProvider {
protected static final String API_DOCS_URI = "/v3/api-docs";
private static final String SWAGGER_VERSION = "3.0";
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;
public GatewayRoutesOasSwaggerResourcesProvider(
RouteLocator routeLocator, GatewayProperties gatewayProperties,
Environment environment, DocumentationCache documentationCache, DocumentationPluginsManager pluginsManager) {
super(environment, documentationCache, pluginsManager);
this.routeLocator = routeLocator;
this.gatewayProperties = gatewayProperties;
}
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
resources.addAll(super.get());
List<String> routes = new ArrayList<>();
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> {
route.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("/**", API_DOCS_URI))));
});
return resources;
}
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion(SWAGGER_VERSION);
return swaggerResource;
}
}
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
@yuebaix Thanks.
It seems SpringFox development is not active now.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
There is no update for several months, not sure this project is still active.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically closed because it has not had recent activity. Please re-open a new issue if this is still an issue.