Ignore Swagger URL based on profiles - spring-boot

I want to ignore the swagger URL's based on active profiles in spring boot application. I found #ApiIgnore and #Hidden, but they hide API irrespective of profile. Here, I want to hide some API's only for PROD but not other profile(i.e., DEV, UAT, etc.,). Is there a way I can achieve this. Please suggest

They are multiple way of doing this, one simple approach (but not elegant at all) is to actually create multiple Docket's for different profiles.
Example:
#Configuration
public class SpringFoxConfig {
#Bean
#Profile("dev")
public Docket getDocketForDev() {
final Set<String> produces = new HashSet<String>();
produces.add(MediaType.APPLICATION_JSON_VALUE);
produces.add(MediaType.APPLICATION_XML_VALUE);
return new Docket(DocumentationType.OAS_30)
.apiInfo(new ApiInfoBuilder()
.title("Note API")
.description("A CRUD API to demonstrate Springfox 3 integration")
.version("0.0.1")
.license("MIT")
.licenseUrl("https://opensource.org/licenses/MIT")
.build())
.produces(produces).consumes(produces)
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
.build();
}
#Bean
#Profile("prod")
public Docket getDocketForProd() {
final Set<String> produces = new HashSet<String>();
produces.add(MediaType.APPLICATION_JSON_VALUE);
produces.add(MediaType.APPLICATION_XML_VALUE);
return new Docket(DocumentationType.OAS_30)
.apiInfo(new ApiInfoBuilder()
.title("Note API")
.description("A CRUD API to demonstrate Springfox 3 integration")
.version("0.0.1")
.license("MIT")
.licenseUrl("https://opensource.org/licenses/MIT")
.build())
.produces(produces).consumes(produces)
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
.build();
}
}
Now after you have multiple docket's per environment you can play with this line of code:
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
and display endpoints based on your conditions per environment.

Related

swagger-ui doesn't list any of the controllers endpoints

I'm trying to add Swagger to a very simple hello word Spring-Boot project.
I'm following this tutorial :
https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api
this is my SwaggerConfig:
#Configuration
#EnableSwagger2
public class SwaggerConfig{
#Bean
public Docket greetingApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.swaggerready"))
.build()
.apiInfo(metaData());
}
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("Spring Boot REST API")
.description("\"Spring Boot REST API for greeting people\"")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0\"")
.build();
}
}
However, the results I have running it is only the first page without any information.
This is the repository if someone wants to see the full code.
https://github.com/ThadeuFerreira/SpringMicro
In class SwaggerConfig you need to change line:
.apis(RequestHandlerSelectors.basePackage("com.example.swaggerready"))
To:
.apis(RequestHandlerSelectors.basePackage("com.example.SpringMicro"))

SpringFox Swagger UI has wrong base url

I got confused with spring fox swagger ui base url, they are not pointing to correct url.
I just deployed a war in a context, so the app is in 127.0.0.1:8080/bff, i managed to add swagger and success, now its running in 127.0.0.1:8080/bff/swagger-ui.html, but when i try to test the api its pointing to 127.0.0.1:8080/bff/v2/api-docs/api/v1/home/profile. Why there is v2/api-docs !?
I know the API list on the swagger-ui is populated from that one, but why it's injected to URL when we test the API? because all of my API lay on the 127.0.0.1:8080/bff/api/v1
This is the screenshot
This is the code.
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Autowired
private GitVersionPropertiesConfig gitVersionPropertiesConfig;
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.globalOperationParameters(
Lists.newArrayList(new ParameterBuilder()
.name("Authorization")
.description("OAUTH2 Token")
.modelRef(new ModelRef("string"))
.parameterType("header")
.required(false)
.build()))
.apiInfo(apiInfo())
.pathMapping("/")
.pathProvider(new RelativePathProvider(null) {
#Override
public String getApplicationBasePath() {
return "/bff/";
}
})
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("/api.*"))
.build();
}
ApiInfo apiInfo() {
String desc = "Bima Friends Forever API<br>"
+ "Current Branch : <b>"+gitVersionPropertiesConfig.getGitBranch()+"</b><br>"
+ "Timestamp : <b>"+gitVersionPropertiesConfig.getGitBuildTime()+"</b>";
return new ApiInfoBuilder()
.title("BFF - Hutchison")
.description(desc)
.version(gitVersionPropertiesConfig.getGitCommitIdAbbrev())
.build();
}
}
This is the temporary fix, but not permanent.
Open browser console and run window.swaggerUi.api.setBasePath('/bff');
Server : Wildfly
Swagger UI Version : 2.7.0
Thanks in advance.
I manage to fix it.. the culprit was jboss-web.xml context
Previously
<jboss-web>
<context-root>/bff/</context-root>
</jboss-web>
Fix :
<jboss-web>
<context-root>/bff</context-root>
</jboss-web>
oh my god...

Support multiple pathmapping in Swagger UI/Spring boot

I am using swagger 2.0 in a Spring boot(version 1.5.9.RELEASE) project.
Swagger works fine but now documentation have hundreds of api and I want to redirect documentation on different different urls.I am having swagger configuration like blow.
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket postsApi() {
return new Docket(DocumentationType.SWAGGER_2).groupName("public-api")
.apiInfo(apiInfo()).select().paths(postPaths()).build();
}
private Predicate<String> postPaths() {
return or(regex("/api/posts.*"), or(regex("/api/.*"), regex("/secure/api/.*")));
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("Swagger API")
.description("Swagger Integration with Spring Boot")
.termsOfServiceUrl(null)
.license(null)
.licenseUrl(null).version("1.0").build();
}
}
Please suggest any way. Thanks in advance.
Finally I break these api's into groups basis on their url as following code segment, creates three group one for Settings, another for Products and last one contains all the other documentation except settings and products.
#Bean
public Docket swaggerSettingsApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Settings")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xyz"))
.paths(regex("/secure/api/v1/settings/.*"))
.build()
.apiInfo(new ApiInfoBuilder().version("1.0").title("Settings API").build())
.globalOperationParameters(operationParameters());
}
#Bean
public Docket swaggerProductApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Product")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xyz.modules.v1"))
.paths(productPaths())
.build()
.apiInfo(new ApiInfoBuilder().version("1.0").title("Product API").build())
.globalOperationParameters(operationParameters());
}
#Bean
public Docket swaggerModuleApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Others")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xyz.modules.v1"))
.paths(postPaths())
.build()
.apiInfo(new ApiInfoBuilder().version("1.0").title("Other Modules API").build())
.globalOperationParameters(operationParameters());
}
private Predicate<String> postPaths() {
return or(regex("^(?=\\/secure\\/api\\/v1\\/)(?!.*(settings|products)).+\\/.*"));
}

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