Springfox not generating Swagger docs correctly for same operation-endpoint, different query parameters - spring

Springfox doesn't generate correctly the swagger doc for a simple case like this one:
GET /api/departments - Gets all department
GET /api/departments?name=IT - Gets a department with name passed as query parameter
This is the Spring Controller:
#ApiOperation(value = "Gets all departments", notes = "", tags = {"departments"})
#RequestMapping(value="/departments", produces=MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.GET)
public List<Department> getAllDepartments(){
...
}
#ApiOperation(value = "Gets a department by name", notes = "", tags = {"departments"})
#RequestMapping(value="/departments", params="name", produces=MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.GET)
public Department getDepartmentByName(#RequestParam String name){
...
}
The generated swagger file only contains the GET /api/departments entry, not a trace of the one with the query filter.
Any workaround?
Swagger Config:
#Bean
public Docket departmentsV1Api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("/.*"))
.build()
.apiInfo(new ApiInfo("Departments Rest API","","v1","","","",""))
.pathMapping("/api")
.securitySchemes(newArrayList(apiKey()))
.securityContexts(newArrayList(securityContext()))
.groupName("departmentsV1");
}

This use case isn't supported by the spec. However you could use the enableUrlTemplating(true) method in your docket to enable rfc6570 support.
There is also an experimental library (springfox-swagger-ui-rfc6570) that can be used as a drop-in replacement for the standard springfox-swagger-ui.
Note: Keep in mind this is in incubation and can change when support is added in the spec.

Related

Swagger overwrites methods with the same path and method but different parameters

Swagger overwrites methods with the same path and method but different parameters
I have an application with Spring Boot 2.3.5.RELEASE, webflux and springfox 3.0.0. I have developed two GET methods with the same path but different parameters, one does not receive parameters and returns a list and others for findAll.
The case is that Swagger only generates the documentation of one of the methods, sometimes the listing, others the paging. How can I tell swagger that they are different methods and document both for me?
My Controller code:
#GetMapping(value = "/foo", params = {"page", "size"})
#ResponseBody
public Mono<ResponseEntity<Mono<Page<FooDTO>>>> findByFilter(FooFilterDTO filter,
#SortDefault(sort = "id", direction = Sort.Direction.DESC) #PageableDefault(value = 10) Pageable pageable) {
//...
}
#GetMapping(value = "/foo")
#ResponseBody
public Mono<ResponseEntity<Flux<FooDTO>>> findAll() {
//...
}
My Swagger configuration:
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Value("${app.version}")
private String version;
#Bean
public Docket docketUsersV1() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(this.fooApiInfo())
.enable(true)
.groupName("foo-api")
.securityContexts(Arrays.asList(securityContext()))
.securitySchemes(Arrays.asList(apiKey()))
.select()
.paths(fooPaths())
.build();
}
private ApiInfo fooApiInfo() {
return new ApiInfoBuilder()
.title("Reactive Foo")
.description("Reactive API")
.version(appVersion)
.build();
}
private Predicate<String> fooPaths() {
return regex("/foo.*");
}
}
As far as I know, you can only define one API path by each HTTP verb (GET, POST...), independently of the optional parameters the API consumer sends.
My advice would be to define a single GET /foo path, with optional parameters page & size (ie. not required)
Then I would have a single entrypoint function in the controller, then redirect to each findByFilter private method or findAll private method depending on whether page & size are defined or not.

How I can ignore PathVariable conditionally on swagger ui using springdoc openapi

I am migrating from springfox 2.9.0 to springdoc-openapi-ui 1.2.33.
I have a requirement to show or hide the PathVariable on swagger ui based on condition.
I have two paths like below
String nameIdentifier = "{fisrtName}/{lastName}"
String nameIdentifier = "{fisrtName}"
I am passing one of the above nameIdentifier based on the requirement.
I am using a single controller for the above paths as shown below
#GetMapping(path = "persons/${nameIdentifier}/display")
public List<Person> getPersons(#PathVariable String fisrtName,
#IgnoreLastName #PathVariable Optional<String> lastName) {
}
In springfox I was able to achieve it using docket.ignoredParameterTypes(IgnoreLastName.class) as shown below.
#Bean
public Docket api() {
Docket docket;
docket = new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("go.controller")).paths(PathSelectors.any()).build()
.apiInfo(apiInfo());
if (!nameIdentifier.contains("lastName")) {
docket.ignoredParameterTypes(IgnoreLastName.class);
}
return docket;
}
But in springdoc open api I am unable to achieve the same.
Your help appreciated in the same.
Coding is done in java
Thanks
You can use #Hidden swagger annotations or #Parameter(hidden = true).
If you can not pass on parameter level, you can set it globally: You will need to upgrade to v1.3.0 of springdoc-openapi-ui.
static {
SpringDocUtils.getConfig().addAnnotationsToIgnore(IgnoreLastName.class);
}

How can we change the default Swagger URL to any other

I have integrated Swagger into my Spring Boot Application. I am able to view the documentation created for a single Controller class , on the default swagger URL i.e - http://localhost:8081/swagger-ui.html#/
How can we change '/swagger-ui.html/' path to any other Custom path .
Also adding the code snippet. I want the url to be like :
http://localhost:8081/swagger#/
#Bean
public Docket usersApi(ServletContext servletContext){
return new Docket(DocumentationType.SWAGGER_2).pathProvider(new RelativePathProvider(servletContext){
#Override
public String getApplicationBasePath() {
return "/swagger" + super.getApplicationBasePath();
}
})
.apiInfo(apiInfo())
.select()
.paths(PathSelectors.regex("/api/v1/.*" ))
.build();
}
Thanks in Advance

Changing title and description of Swagger UI using Springfox

I am building a Spring Boot application and documenting it using a Swagger UI using the Springfox Swagger UI. I've got everything documented, but want to customize the title and description but can't figure out how. For example, in this image: https://springfox.github.io/springfox/docs/current/images/springfox-swagger-ui.png the title is "Springfox petstore API" and the description is Lorem Ipsum. But in my Swagger UI, both the title and the description say "API Documentation". I have tried using the #SwaggerDefinition annotation, but it does not seem to do anything.
I recommend you to use swagger editor, then you can auto generate Spring Boot server from the API docs, using "Generate Server" option from Top Menu. It is really great for generating an API for the first time.
If you want to set from the YAML you must provide this fields at the info section:
info:
version: "1.0.0"
title: My API title
description: "Awesome description"
From the code, check the generated classes from Swagger editor and compare it with your code. You could set description and title, setting the corresponding attributes on the ApiInfo Builder object, which is inside the class SwaggerDocumentationConfig.
Here you have the code:
#javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2017-10-05T14:03:51.916-03:00")
#EnableSwagger2
#Configuration
public class SwaggerDocumentationConfig {
ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("My API Title")
.description("Awesome description")
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.termsOfServiceUrl("")
.version("1.0.0")
.contact(new Contact("", "", "contact#contact.com.uy"))
.build();
}
#Bean
public Docket customImplementation() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.mypackage.api"))
.build()
.apiInfo(apiInfo());
}
}
If none of this makes sense to you, show me a little more of your code to know how you are using Springfox and I can help you better.
Bests regards!

Spring + Springfox + Header Parameters

#RequestMapping(...)
public Foo getFoo(#HeaderParam("header") final String header) {
...
}
Adding a #HeaderParam method parameter as above springfox picks it up and when I look at the swagger-ui it has a field for the header. This is exactly what I want. Is there a way I can tell springfox to include this header parameter on a set of methods without having to include the parameters on the method itself? What we really have going on is a servlet filter which uses the header and we'd like an easy to set it through the swagger-ui.
You could use the globalOperationParametersin the docket definition. For e.g.
new Docket(...)
.globalOperationParameters(
Arrays.asList(new ParameterBuilder()
.name("header")
.description("Description of header")
.modelRef(new ModelRef("string"))
.parameterType("header")
.required(true)
.build()))
See #22 in the documentation for more information.
One more explained answer for same :-
#Bean
public Docket api() {
//Adding Header
ParameterBuilder aParameterBuilder = new ParameterBuilder();
aParameterBuilder.name("headerName").modelRef(new ModelRef("string")).parameterType("header").required(true).build();
List<Parameter> aParameters = new ArrayList<Parameter>();
aParameters.add(aParameterBuilder.build());
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.any()).paths(PathSelectors.any()).build().apiInfo(apiInfo()).pathMapping("").globalOperationParameters(aParameters);
}

Resources