How can we change the default Swagger URL to any other - spring-boot

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

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);
}

Keep same URL but contract changes in Spring Boot REST Open API 3?

I am using Spring Boot and REST and Open API 3 implementation. In this example, v1 Group has List implementation - all data will get in List, in v2 Group has pagination implementation - all data will come in the form of pages.
For the consumer, we don't want to change endpoint url for them to be consume.
Endpoint which returns list.
#GetMapping(value = "/contacts", headers = {"Accept-version=v1"})
public ResponseEntity<List<Contact>> findAll() {
List<Contact> contacts = contactService.findContactList();
return new ResponseEntity<>(contacts, HttpStatus.OK);
}
Endpoint with Pagination
#GetMapping(value = "/contacts", headers = {"Accept-version=v2"})
public ResponseEntity<List<Contact>> findAll(Pageable pageable) {
Page<Contact> contactPages = contactService.findContactPageable(pageable);
return new ResponseEntity<>(contactPages, HttpStatus.OK);
}
I want V1 endpoint to be shown in GroupedOpenApi and v2 endpoint to be shown in the GroupedOpenApi2. Any suggestions ?
Lets assume you put the two endpoints in different packaged and then use the Following GroupedOpenApi definition:
#Bean
public GroupedOpenApi groupOpenApiV1() {
return GroupedOpenApi.builder()
.setGroup("v1")
.packagesToScan("test.org.springdoc.api.v1")
.build();
}
#Bean
public GroupedOpenApi groupOpenApiV2() {
return GroupedOpenApi.builder()
.setGroup("v2")
.packagesToScan("test.org.springdoc.api.v2")
.build();
}

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);
}

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

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.

Resources