Springfox: How to manually add api paths to swagger-ui? - spring-boot

When configuring a Docket we have to specify the base package where to look for api endpoints. Is it possible to add manually an endpoint which is not mapped to any controller?
I have a legacy application which is a simple Zuul server but it has a swagger-ui, the goal is to specifiy endpoints that are proxied by zuul?
#Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.globalOperationParameters(getHeaders()).select()
.apis(RequestHandlerSelectors.basePackage("package.controllers"))
.additionalApis(Method.PUT, "/my/manual/endpoint") // This does not exist
.paths(PathSelectors.any())
.build();
}
Thanks

Related

Adding base path to swagger documentaion

I am trying to change the base path of swagger codumentation. Currently I have
#RequestMapping(path = "/api/resourceName/v1")
and swagger config
return new Docket(DocumentationType.SWAGGER_2).
select()
.apis(RequestHandlerSelectors.basePackage("com.company"))
.paths(PathSelectors.ant("/api/**"))
.build()
.apiInfo(apiInfo());
This is giving swagger base path as "basePath": "/"
I want to add base path as "basePath": "/api" so I followed diff threads like this How to change basePath for Springfox Swagger 2.0 and added
return new Docket(DocumentationType.SWAGGER_2).
select()
.apis(RequestHandlerSelectors.basePackage("com.company"))
.paths(PathSelectors.ant("/api/**"))
.build()
.apiInfo(apiInfo())
.pathProvider(new RelativePathProvider(servletContext) {
#Override
public String getApplicationBasePath() {
return "/api";
}
});
now the base path is changed to "basePath": "/api" and I updated my path mapping to #RequestMapping(path = "/resourceName/v1") as base has been added.
When I send the request from swagger, the request is going to /api/resourceName/v1 but the service returns 404.
When I send the request through postman for /resourceName.v1 then it works.
So the api is registred as /resourceName/v1 and the base is just added by swagger on top of it and will not work if the request sent throguh swagger UI
Then I added server.servlet-path=/api to application.properties to register basepath in the request mapping and now swagger shows the base path as /api without needing additional configuration.
But the problem is now swagger documentation is available at http://localhost:8080/api/swagger-ui.html instead of http://localhost:8080/swagger-ui.html. As we have all our other services doc at http://host/swagger-ui.html this is not useful.
Is there any way to add the base and still access the doc at http://host/swagger-ui.html and api's works as expected fro swagger and postman
Yes, you can add base path for all swagger requests. I used following config for this purpose:
#Configuration
#EnableSwagger2
public class SpringFoxConfig {
#Bean
public Docket api() {
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
docket.pathMapping("api");
return docket;
}
}
Hope this helps.
There is way to change the api-doc base path using properties defined in application.properties file.
The properties are:
springfox.documentation.openApi.v3.path=/external/api/app/v3/api-docs
springfox.documentation.swaggerv2.path=/external/api/app/v2/api-docs
This can help you to change the path.

Spring Boot + Swagger-Ui yml generate

Create a swagger-ui with the yaml file generated by swagger-editor
Creating an auto swagger-ui using Annotation was successful.
But I do not know how to create Swagger-ui with yaml created with swagger-editor. Is there anyone who can explain in detail? The development environment uses SpringBoot 2.0.4.
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket getApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(paths())
.build();
}
private Predicate<String> paths() {
return Predicates.and(
PathSelectors.regex("/shop.*"),
Predicates.not(PathSelectors.regex("/error.*")));
}
}
The above code can make all the APIs inside the server Swagger-ui.
However, I would like to configure swagger-ui with the yaml file that I wrote myself through the swagger-editor.

SpringCloud Config Server: Path Mapping Conflict with SwaggerUI

I am running a SpringBoot config server (with Vault backend) and tried to add Springfox SwaggerUI to it. But since I do not want a prefix (spring.cloud.config.server.prefix) for my config server, the path mapping between the config server and SwaggerUI results in a conflict.
All my clients ask the config server with the following pattern:
{config-server-host}/{application-name}/{profile}
For example:
{config-server-host}/test-app-one/dev
{config-server-host}/test-app-two/prod
But my SwaggerUI path maps to:
{config-server-host}/swagger-ui.html
As a consequence, the config server complains that the app "swagger-ui" cannot be found or that no profile was specified.
This is the configuration of my Docket bean for the SwaggerUI:
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.paths(not(regex("/error.*")))
.paths(any())
.build()
.pathMapping("/");
}
private ApiInfo apiInfo() {
Contact contact = new Contact({secret}, {secret}, {secret});
return new ApiInfoBuilder().title({secret})
.description({secret})
.version({secret})
.contact({secret})
.build();
}
}
This all results in the following question: I cannot have a prefix for the config server and I want the SwaggerUI url mapped to the standard. Is there any possibility to tell the config server that it should exclude the /swagger* paths?
The spring.cloud.config.server.prefix parameter in the bootstrap.properties file fixed the issue for me.

Consider zuul route in Swagger documentation

is it possible to consider the zuul filter (manual or automatic) to show in the swagger?
The issue is the following:
we have a microservice which is the single point of entry for our application and which holds all swagger documentation. in fact it works as a fasade, so it routes the request to the corresponding microservices inside our application. Unfortunately, zuul sometimes it adds something to the route or removes something. therefore the swagger documentation is incorrect, as the base-path is slightly different.
is there any possiblity to influence this?
swagger docket is used with simple lookup:
#Bean
public Docket swaggerSpringfoxDocket() {
this.log.debug("Starting Swagger");
StopWatch watch = new StopWatch();
watch.start();
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.forCodeGeneration(false)
.select()
.paths(regex("/api/.*"))
.build();
watch.stop();
this.log.debug("Started Swagger in {} ms", watch.getTotalTimeMillis());
return docket;
}

Spring Boot Actuator / Swagger

I'm working on Spring Boot application and i use Swagger for the documentation.
I have adding Spring Boot Actuator on my application, but now i want to add the new services creating by actuator (/health /metrics ..) on my swagger documentation.
I don't find how configure Actuator and Swagger.
You can configure in Swagger which paths you want to be added to the documentation :
#Bean
public Docket appApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
...
}
will display all available endpoints.
.paths(PathSelectors.any("/mypath/**")) will limit only to endpoints exposed in mypath.
In order to display spring-boot-actuator endpoints in springdoc-openapi, simply add the following property:
springdoc.show-actuator=true
Update: 26-04-2017, updated implemention. Credits to Andy Brown for the tip.
Due to our coding convention, we don't have a specific prefix for our endpoints, so I was looking for a solution to exclude the actuator endpoints, rather than to include my own paths.
I've came up with the following config to only exclude the actuator endpoints.
This way, I don't have to update the config once I add new endpoints nor do I have to prefix my own endpoints to distinguish them from the actuator endpoints.
/**
* This enables swagger. See http://localhost:8080/v2/api-docs for the swagger.json output!
* #param actuatorEndpointHandlerMapping this endpoint handler mapping contains all the endpoints provided by the
* spring actuator. We will iterate over all the endpoints and exclude them from the swagger documentation.
* #return the docket.
*/
#Autowired
#Bean
public Docket swaggerSpringMvcPlugin(final EndpointHandlerMapping actuatorEndpointHandlerMapping) {
ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2)
.useDefaultResponseMessages(false)
.apiInfo(apiInfo())
.securitySchemes(securitySchemes())
.select();
// Ignore the spring-boot-actuator endpoints:
Set<MvcEndpoint> endpoints = actuatorEndpointHandlerMapping.getEndpoints();
endpoints.forEach(endpoint -> {
String path = endpoint.getPath();
log.debug("excluded path for swagger {}", path);
builder.paths(Predicates.not(PathSelectors.regex(path + ".*")));
});
return builder.build();
}
ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2)
.useDefaultResponseMessages(false)
.apiInfo(apiInfo())
.securitySchemes(securitySchemes())
.select()
.apis(RequestHandlerSelectors.any())
.paths(Predicates.not(PathSelectors.regex("/actuator.*")))
.build();
Hi, You can exclude path on regex and you can chain them.
Move the actuator endpoints into a context path through your application.properties file.
management.context-path=/manage
Then you can exclude that path from swagger
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(Predicates.not(PathSelectors.regex("/manage.*")))
.build();
}
You might want to exclude the error controller too
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(Predicates.not(PathSelectors.regex("(/manage.*|/error)")))
.build();
}
Alternatives:
a) Exclude path with a NOT in the Regex?
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("^((?!/error).)*")) // exclude Basic Error Controller
.build();
}
b) or chain and negate a Predicate:
PathSelectors.any()
.and(PathSelectors.regex("/error").negate())
.and(PathSelectors.regex("/manage.*").negate());

Resources