12

I would like the OpenAPI Generator (https://github.com/OpenAPITools/openapi-generator) to be able to generate Pageable parameter in API according to the implementation in Spring Boot Data. I've been trying to find a suitable, out of the box solution, but couldn't find one.

Ideally, this Pageable parameter should be added only to GET methods in a following manner:

default ResponseEntity<User> getUser(@ApiParam(value = "value",required=true) @PathVariable("id") Long id, **Pageable pageable**)

So after implementing this interface in my Controller I would need to override it and having this aforementioned Pageable parameter. I don't want to have separate parameters for size or page, only this Pageable here.

Thanks for any tips and help!

William Cheng
  • 10,137
  • 5
  • 54
  • 79
Bloodlex
  • 447
  • 2
  • 6
  • 16
  • As far as I know that is not possible without adding size/page to the api. Why do you want to hide it? Without it nobody knows it is paging... – Martin Hauner Apr 20 '20 at 16:19
  • @MartinHauner We would like to have page,size,sort in our openAPI .yaml file, so our other teams know that the paging is there, but in our generated API as a backend, we would like to have only this Pageable param, since spring will handle that having page,size,sort param and transform it into Pageable object – Bloodlex Apr 21 '20 at 17:15

2 Answers2

9

Unfortunately this is no final solution but it is half way. Maybe it is of help anyway.

By defining the pageable parameters (size, page etc.) as an object query parameter it is possible to tell the generator to use the Spring object instead of generating a Pageable class from the api. This is done by an import mapping.

in gradle:

openApiGenerate {
    ....
    importMappings = [
        'Pageable': 'org.springframework.data.domain.Pageable'
    ]
}

which tells the generator to use the Spring class instead of the one defined in the api:

openapi: 3.0.2
info:
  title: Spring Page/Pageable API
  version: 1.0.0

paths:
  /page:
    get:
      parameters:
        - in: query 
          name: pageable
          required: false
          schema:
            $ref: '#/components/schemas/Pageable'
      responses:
        ...

components:
  schemas:
    Pageable: 
      description: minimal Pageable query parameters
      type: object
      properties:
        page:
          type: integer
        size:
          type: integer

The issue with the mapping is that the generator still adds a @RequestParam() annotation and that breaks it again. It only works if it is NOT annotated.

If you are a bit adventurous you could try openapi-processor-spring (i'm the author). It it does handle the example above. But it may have other limitations you don't like.

Martin Hauner
  • 1,593
  • 1
  • 9
  • 15
  • thanks! I wish it was more configurable than it seems to be, great idea with creating your processor, I still need to check this out :) – Bloodlex May 03 '20 at 06:19
  • What do you mean by 'works if it is not annotated'? Annotations as I understand are also added by openapi generator plugin. – zygimantus Aug 09 '21 at 17:46
  • at time of writing, (I don't know if it still the case) the generator added the `@RequestParam()` annotation to the `pageable` parameter of the controller method. This confused Spring and the automatic binding of the `page`& `size` parameters to the `Pagable` object did not work. It did work only if the `Pagable` parameter was not annotated with `@RequestParam`. – Martin Hauner Aug 13 '21 at 06:19
  • Kotlin-Spring v5.3.1 generates a "pageable: Pageable?" parameter without @RequestParam annotation. – OliverE Jan 28 '22 at 13:16
3

I have another solution, using 'openapi-generator' u can give a vendorextension flag in the spec file 'x-spring-paginated'

info:
  title: Spring Page/Pageable API
  version: 1.0.0

paths:
  /page:
    get:
      x-spring-paginated: true
      responses:
        ...

You might experience an issue with spring-doc where you either can add the missig dependency or change the documentation-provider under the configOptions to source.

I.G. for the maven plugin

...
<configuration>
  ...
  <configOptions>
   <documentationProvider>source</documentationProvider>
   ...
  </configOptions>
</configuration>

nikloe
  • 31
  • 3