Open API 3 - How to read Spring Boot Pagination Properties? - spring

I am using Spring Boot + Spring Rest Pagination + Open API 3.
#Operation(summary = "Find Contacts by name", description = "Name search by %name% format", tags = { "contact" })
#ApiResponses(value = {
#ApiResponse(responseCode = "200", description = "successful operation", content = #Content(array = #ArraySchema(schema = #Schema(implementation = Contact.class)))) })
#Parameter(in = ParameterIn.QUERY, description = "Zero-based page index (0..N)", name = "page"
, content = #Content(schema = #Schema(type = "integer", defaultValue = "0")))
#Parameter(in = ParameterIn.QUERY, description = "The size of the page to be returned", name = "size"
, content = #Content(schema = #Schema(type = "integer", defaultValue = "20")))
#Parameter(in = ParameterIn.QUERY, description = "Sorting criteria in the format: property(,asc|desc). "
+ "Default sort order is ascending. " + "Multiple sort criteria are supported."
, name = "sort", content = #Content(array = #ArraySchema(schema = #Schema(type = "string"))))
#GetMapping(value = "/contacts")
public ResponseEntity<List<Contact>> findAll(Pagination pagination) {
List<Contact> contacts = new ArrayList<>();
contacts.add(Contact.builder().address1("Address1").address2("Address2").build());
return new ResponseEntity<>(contacts, HttpStatus.OK);
}
Since I'm using Spring Boot Application. I've configured below configurations,
# Added for Pagination
spring.data.web.pageable.default-page-size=25
spring.data.web.pageable.page-parameter=page
spring.data.web.pageable.size-parameter=size
spring.data.web.sort.sort-parameter=sort
Is there any way we can configure above properties for the Open API 3 specification instead of making it hard-coded ?

The support for Pageable of spring-data-commons is available. If only want to enable the support of spring Pageable Type, you can just enable it using:
SpringDocUtils.getConfig().replaceWithClass(org.springframework.data.domain.Pageable.class,
org.springdoc.core.converters.models.Pageable.class);
Alternately, the projects that use Pageable type can aslo add the follwing dependency together with the springdoc-openapi-ui dependency which will enable the support of spring.data.rest.default... properties and #PageableDefault annotation as well:
Note that latest.version should be at least equal to v1.4.5 which adds this new features
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-data-rest</artifactId>
<version>latest.version</version>
</dependency>
More details are available on the F.A.Q:
https://springdoc.org/faq.html#how-can-i-map-pageable-spring-date-commons-object-to-correct-url-parameter-in-swagger-ui

I've also was looking for this and discovered that SpringDoc now has an annotation to add the needed Parameters, #PageableAsQueryParam. I'm using springdoc-openapi-ui-1.6.4
Just make sure that you hide the Pageable object with #Parameter(hidden=true), as it will not be automatically hidden.
An example
#GetMapping("/customerQuery")
#PageableAsQueryParam
public List<PartyDTO> getCustomers(String name, #Parameter(hidden = true) Pageable pageable){
return partyService.queryCustomer(name, pageable).getContent();
}
will result into:
Used dependencies:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.4</version>
</dependency>

Related

How to add enum for attribute so that it comes as dropdown in swagger ui using spring webflux,openapi 3

I am writing a reactive application using webflux with springdoc-openapi(v 1.4.3). Below is the router class
#Configuration
public class AppRouter {
#RouterOperation(path = "/app", produces = {
MediaType.APPLICATION_JSON_VALUE},
beanClass = Apphandler.class, method = RequestMethod.GET, beanMethod = "getApp",
operation = #Operation(operationId = "getApp", responses = {
#ApiResponse(responseCode = "200", description = "successful operation",
content = #Content(schema = #Schema(implementation = AppResponse.class)))
},
parameters = {
#Parameter(in = ParameterIn.HEADER, name = "Authorization ",required = true),
#Parameter(in = ParameterIn.QUERY, name = "id",required = true),
#Parameter(in = ParameterIn.QUERY, name = "idType")
}
))
#Bean
public RouterFunction<ServerResponse> route(Apphandler handler) {
return RouterFunctions.route(GET("/app"), handler::getApp);
}
}
Corresponding to above api definition below swagger response is coming
pom contains the below dependency for openapi
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-core</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-ui</artifactId>
<version>1.4.3</version>
</dependency>
Basically I my required swagger should look like below image. How to achieve it?
Below queries:
Q1. I have made id and authorization as required=true but even when I am running without providing them from swagger it is not giving any warning message. Ideally it should give some warning message. How to get that message
Q2. id value needs to follow some REGEX pattern like [a-zA-Z0-9]{5,15}.How to add this regex check. Also if I am providing id which does not follow this pattern should give some warning message? How to achieve it?
Q3. How to add enum for parameter?
If you want to generate swagger documentation indicating that idField is an enumerated, you can use the schema property of the #Parameter annotation:
#Parameter(in = ParameterIn.QUERY, name = "idType", schema = #Schema(implementation = EIndType.class))
Where EIndType is the enum where you define all the possible values:
public enum EIndType {
SITEGEOID("siteGeoId"),
SITERKST("siteRkst"),
CITYGEOID("cityGeoId"),
CITYRKST("cityRkst");
private final String value;
public String getValue() {
return value;
}
}
I got the answer
Q1 answer
#Parameter(in = ParameterIn.HEADER, name = "Authorization ",required = true,schema =#Schema(minLength = 1))
Q2 answer
#Parameter(in = ParameterIn.QUERY, name = "id",required = true,schema = #Schema(minLength = 5,maxLength = 15,pattern = "[a-zA-Z0-9]{5,15}"))

Springfox to OpenAPI Springdocs migration: #ApiImplicitParam(allowMultiple=true) equivalent?

I'm migrating from springfox to OpenAPI springdocs and I have to replace
#ApiImplicitParam(allowMultiple=true)
#ApiImplicitParam is replaced with #Parameter, but what is the OpenAPI springdoc equivalent to allowMultiple=true?
Reference: https://springdoc.org/migrating-from-springfox.html
You can use the below approach
Before
#ApiImplicitParam(value="Filter by type", allowableValues="typeA,typeB,typeC",
allowMultiple=false)
After
#Parameter(description = "Filter by type",
schema=#Schema(type="string",
allowableValues={"typeA","typeB","typeC"}, defaultValue = "typeA"))
This answer is taken from what #tomjankes put in his comment to the question -> the answer is to add explode=Explode.TRUE. Here's an example piece of code that worked for me:
#Parameters({
#Parameter(name = "sort", **explode = Explode.TRUE**, schema = #Schema(type = "string"), in = ParameterIn.QUERY, description = "Sort setting in the format of: property(,asc|desc). Default sort order is ascending. Multiple sort settings are supported.")
})

Hidden parameter in springdoc-openapi doesn't work

I have Spring Boot application with version 2.3.0.
and springdoc-openapi-webflux-ui in version 1.4.1.
I have annotated parameter in operation like this.
parameters = {
#Parameter(
hidden = true, schema = #Schema(implementation = Boolean.class),
in = ParameterIn.QUERY, name = DO_NOT_FORWARD
)
With hidden = true I expected that this parameter will not be visible in swagger-ui. But it is.
Did I misunderstood this parameter or is it not doing what it was supposed to do?
I want this parameter to be in api-docs, to have generated client able to use this parameter, but I want it invisible in swagger-ui
Try
#Parameter(name = "paramName", hidden = true)
#GetMapping("/example")
public Object example(String paramName) {
return null;
}
instead of
#Operation(
parameters = {
#Parameter(name = "paramName", hidden = true)
}
)
#GetMapping("/example")
public Object example(String paramName) {
return null;
}
You just make sure that the name of in the #Parameter annotation, is the exact name of the operation parameter you want to hide.
You can have a look at the documentation as well:
https://springdoc.org/faq.html#how-can-i-hide-a-parameter-from-the-documentation-
If you are still having coniguration issue, you can add the code of sample HelloController that reproduces your problem, or you can add the link to a minimal, reproducible sample in github.
As per the doc
#GetMapping("/example")
fun someCall: Response (
#Parameter(hidden = true) String paramName
) {
return response;
}

Automatically adding #ImplicitParams with specific type of method argument of Spring Controller

Previously, I had Spring controller as below.
#RequestMapping(method = GET)
public List<TheResponse> getResponses(
#RequestParam(defaultValue = "1") int offset,
#RequestParam(defaultValue = "10") int limit) {
Pagination pagination = new Pagination(offset, limit);
...
return someResponse;
}
Swagger was generating document of this method with correct parameters information.
Later I created PaginationArgResolver by implementing HandlerMethodArgumentResolver. After that, I have to update the method as below, and apply #ApiImplicitParams to make it work with Swagger.
#ApiImplicitParams({
#ApiImplicitParam(name = "offset", dataType = "int", defaultValue = "1"),
#ApiImplicitParam(name = "limit", dataType = "int", defaultValue = "10")
})
#RequestMapping(method = GET)
public List<TheResponse> getResponses(#ApiIgnore Pagination pagination) {
...
}
Is there anyway #ImplicitParams is applied automatically whenever Pagination type argument is found?
OR
If I expose #PaginationSupported annotation, can I process it to achieve same results?
I am currently using springfox v2.4.0.
PS. I can edit source of Pagination class, in case some swagger annotation is needed there.
Why adding #ApiIgnore springfox will resolve these attributes inside the class automatically. When you want to add default values and other stuff you can add the #ApiParam annotation to the class attributes as well.
class Pagination {
#ApiParam(defaultValue = "1")
private int offset;
// [..]
}

Using #RequestParam annotated method with swagger ui

I am using Springfox libraries to generate documentation for REST service and display it in Swagger UI. I followed the directions in Springfox documentation.
I have one controller, which uses parameters from query string and the method is mapped as following:
#ApiOperation(value = "")
#RequestMapping(method = GET, value = "/customcollection/{id}/data")
public Iterable<CustomeType> getData(#ApiParam(value = "The identifier of the time series.")
#PathVariable String id,
#ApiParam(name = "startDate", value = "start date", defaultValue = "")
#RequestParam("startDate") String startDate,
#ApiParam(name = "endDate", value = "end date", defaultValue = "")
#RequestParam("endDate") String endDate)
The resulting mapper in swagger-ui then displayed as:
GET /customcollection/{id}/data{?startDate,endDate}
Parameters are displayed correctly in the UI:
But when I click on Try it Out, the request URL is misformed:
http://localhost:8080/customcollection/1/data{?startDate,endDate}?startDate=1&endDate=2
How can it be fixed?
This was caused by the line
enableUrlTemplating(true)
in Docket configuration which I copied from example and forgot to remove.
After removing this line everything is working as expected.

Resources