Swagger Documentation for Spring Interface Palette

I developed a microservice using Spring Boot. The REST API documentation is done using Swagger. Some REST resources use Spring concepts for free page numbering. The following is an example:

@RequestMapping(value = "/buckets", method = GET) public PagedResources list(Pageable pageable, PagedResourcesAssembler assembler) { return bucketService.listBuckets(pageable, assembler); } 

If I open the Swagger page, the following form will be available for the resource:

enter image description here

My problem is that the pageable parameter is detected using the content type application / json, and I don't know how to pass the value, for example, to resize the page. All values โ€‹โ€‹seem to be ignored.

Is it possible to pass request parameters as a JSON object? or can you configure Swagger to generate independent request parameter fields for the getters contained in the Pageable interface?

Please note that I am using Springfox with Gradle:

 compile 'io.springfox:springfox-spring-web:2.3.1' compile 'io.springfox:springfox-swagger2:2.3.1' compile 'io.springfox:springfox-swagger-ui:2.3.1' 
+21
json spring rest swagger
source share
7 answers

This is a known issue with Spring-Fox. See Issue # 755 . Based on zdila comment 2 , the current alternative is to add @ApiImplicitParams, which is not perfect, but it really works.

 @ApiImplicitParams({ @ApiImplicitParam(name = "page", dataType = "integer", paramType = "query", value = "Results page you want to retrieve (0..N)"), @ApiImplicitParam(name = "size", dataType = "integer", paramType = "query", value = "Number of records per page."), @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query", value = "Sorting criteria in the format: property(,asc|desc). " + "Default sort order is ascending. " + "Multiple sort criteria are supported.") }) 

[ Swagger UI showing @ApiImplicitParams for Pageable]

1 https://github.com/springfox/springfox/issues/755

2 https://github.com/springfox/springfox/issues/755#issuecomment-135059871

+28
source share

Based on Vineet Bhatia's answer, you can wrap the solution in a custom annotation for reuse:

 @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @ApiImplicitParams({ @ApiImplicitParam(name = "page", dataType = "int", paramType = "query", value = "Results page you want to retrieve (0..N)"), @ApiImplicitParam(name = "size", dataType = "int", paramType = "query", value = "Number of records per page."), @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query", value = "Sorting criteria in the format: property(,asc|desc). " + "Default sort order is ascending. " + "Multiple sort criteria are supported.") }) @interface ApiPageable { } 

Which can then be used like this:

 @ApiPageable public Page<Data> getData(Pageable pageRequest) { 
+14
source share

Vineet Bhatia's answer with @ApiImplicitParams looks great. But I came across a situation where @ApiIgnor and @ApiParam(hidden = true) do not work, and you can still observe the asembler and pageable parameters. I fixed this problem by adding the following line

 docket.ignoredParameterTypes(Pageable.class, PagedResourcesAssembler.class); 

in the Docket bean in my SwaggerConfig .

+8
source share

Vineet Bhatia's answer will have a validation problem if you are not working on localhost. He will argue that for integer parameters they do not match the json scheme.

So, I changed the integer to a string:

  @ApiImplicitParams({ @ApiImplicitParam(name = "page", dataType = "string", paramType = "query", value = "Results page you want to retrieve (0..N)"), @ApiImplicitParam(name = "size", dataType = "string", paramType = "query", value = "Number of records per page."), @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query", value = "Sorting criteria in the format: property(,asc|desc). " + "Default sort order is ascending. " + "Multiple sort criteria are supported.") }) 
+2
source share

For people who want to solve this problem in 2019. This configuration through the documentation of Springfox works fine, except that you cannot specify a description for the parameters.

The code is here.

https://github.com/springfox/springfox/blob/ef1721afc4c910675d9032bee59aea8e75e06d27/springfox-data-rest/src/main/java/springfox/documentation/spring/data/rest/configuration/SpronDataRestJest

+2
source share

The answer to the question of validation is indicated by Eugene.

Using

 @ApiImplicitParams({ @ApiImplicitParam(name = "page", dataType = "int", paramType = "query", value = "Results page you want to retrieve (0..N)"), @ApiImplicitParam(name = "size", dataType = "int", paramType = "query", value = "Number of records per page."), @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query", value = "Sorting criteria in the format: property(,asc|desc). " + "Default sort order is ascending. " + "Multiple sort criteria are supported.") }) 

throws an exception:

 Illegal DefaultValue for parameter type integer java.lang.NumberFormatException: For input string: "" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68) at java.base/java.lang.Long.parseLong(Long.java:709) at java.base/java.lang.Long.valueOf(Long.java:1151) at io.swagger.models.parameters.AbstractSerializableParameter.getExample(AbstractSerializableParameter.java:412) at jdk.internal.reflect.GeneratedMethodAccessor366.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:688) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155) at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119) at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79) 

(at least in the case of springfox-swagger2 and springfox-swagger2-ui version 2.9.2)

You can avoid the exception by following Eugeneโ€™s answer or by adding default values โ€‹โ€‹and example values โ€‹โ€‹for integer parameters:

 @ApiImplicitParams({ @ApiImplicitParam(name = "page", dataType = "int", paramType = "query", value = "Results page you want to retrieve (0..N)", defaultValue = "0", example = "2"), @ApiImplicitParam(name = "size", dataType = "int", paramType = "query", value = "Number of records per page.", defaultValue = "20", example = "10"), @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query", value = "Sorting criteria in the format: property(,asc|desc). " + "Default sort order is ascending. " + "Multiple sort criteria are supported.") }) 
0
source share

Although the solution with implicit parameters works, it introduces a lot of extra fragile code. In the end, we went with the following solution:

 @GetMapping(value = "/") public HttpEntity<PagedResources<Item>> getItems( @RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, PagedResourcesAssembler assembler) { Page<Item> itemPage = itemService.listItems(PageRequest.of(page, size, Sort.unsorted())); return new ResponseEntity<>(assembler.toResource(itemPage), HttpStatus.OK); } 

We pass PageRequest (which implements Pageable ) to our service, which returns Page . (all from org.springframework.data.domain ).

org.springframework.data.web.PagedResourcesAssembler is implemented using the controller method and allows you to display elements in org.springframework.hateoas.PagedResources

We did not need dynamic sorting, so we omitted it; adding sorting comes with some difficulties since springfox does not work well with org.springframework.data.domain.Sort.

-one
source share

All Articles