Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add QueryString documentation when using TransferObject with @ModelAttribute as single argument #3029

Discussion options

I'd like to add OpenAPI documentation to my project but I have the following problem :
I have a lot of RestController where th eonly input of the methods is a TransferObject with the @ModelAttribute annotation to map each field of the Transfer Object as a query parameter. In my real life scenario not every field is used for every request, so I would like to add some sort of documentation to specify which fields are used .
I have no idea how to achieve this result, can someone help ?
I'd like to add annotation to the RestController class, leaving the TO as it is.
Here I have an example of what I have in my project : https://github.com/angelomarzocchi/springdocdemo
And this is the documentation I have right now :

openapi: 3.0.1
info:
 title: OpenAPI definition
 version: v0
servers:
- url: http://localhost:8080
 description: Generated server url
paths:
 /product:
 get:
 tags:
 - product-controller
 operationId: getProductTOsByFilter
 parameters:
 - name: filter
 in: query
 required: true
 schema:
 $ref: "#/components/schemas/ProductTO"
 responses:
 "200":
 description: OK
 content:
 '*/*':
 schema:
 type: array
 items:
 $ref: "#/components/schemas/ProductTO"
components:
 schemas:
 ProductTO:
 type: object
 properties:
 productID:
 type: string
 productName:
 type: string
 weight:
 type: number
 format: float
 description:
 type: string

The result I want is to have productID and productName as parameters in the yml documentation.
Something like :

openapi: 3.0.1
info:
 title: OpenAPI definition
 version: v0
servers:
- url: http://localhost:8080
 description: Generated server url
paths:
 /product:
 get:
 tags:
 - product-controller
 operationId: getProductTOsByFilter
 parameters:
 - name: productID
 in: query
 required: false
 - name: productName
 in: query
 required: false
 responses:
 "200":
 description: OK
 content:
 '*/*':
 schema:
 type: array
 items:
 $ref: "#/components/schemas/ProductTO"
components:
 schemas:
 ProductTO:
 type: object
 properties:
 productID:
 type: string
 productName:
 type: string
 weight:
 type: number
 format: float
 description:
 type: string

Thank you everyone in advance

You must be logged in to vote

I believe a possible approach could be to introduce a meta-annotation similar to the one introduced here, and then make it carry a number of annotations that describe the query parameters that you have (and you could probably make the annotation take an argument, so you could controller the required value for each annotation?).

The annotation that I am thinking of would be:

@Parameter(name = "queryValue", in = ParameterIn.QUERY, example = "1", schema = @Schema(type = "number"))

from swagger annotations.

Replies: 1 comment 7 replies

Comment options

It seems to have been discussed before and then it was a no #119 (and a second time more recently #2439).

I'd like to add annotation to the RestController class, leaving the TO as it is

Could we elaborate on this reasoning? Personally I would like the api-object itself to describe what expectations it has on data (i.e., whether it is required or not), so I would most likely create several different ProductXTO to describe the different permutations of required field combinations that can exists (this is of course not viable if ProductTO in reality has many more fields than 4).

You must be logged in to vote
7 replies
Comment options

Hi Mattias, first of all thank you for answering . I understand that ModelAttribute is not supported, that's unfortunate. So the only way to actually have query params on my REST APIs is to add all the fields in the RestController methods with the RequestParam annotation, right ?

Changing the TOs has an impact on external systems over which I have no control, so I cannot make any changes on these classes for now. That's why I was looking for a way to add the metadata I need for documentation directly on RestController

Comment options

I believe a possible approach could be to introduce a meta-annotation similar to the one introduced here, and then make it carry a number of annotations that describe the query parameters that you have (and you could probably make the annotation take an argument, so you could controller the required value for each annotation?).

The annotation that I am thinking of would be:

@Parameter(name = "queryValue", in = ParameterIn.QUERY, example = "1", schema = @Schema(type = "number"))

from swagger annotations.

Answer selected by angelomarzocchi
Comment options

Also, just out of curiosity of how others manage their openapi contracts, how would introducing additional TOs affect external consumers? Do they automatically pull your specification and attempt to generate a client based upon it? Because technically you changing your specification should not affect anything as long as your service offers the same functionality. E.g., you could rename a model or add new fields, but as long as your service still accepts the json/query structure that is serialized based on the code they use for your old specification, then there is no issue.

The only issue might be that they get annoyed that their generated client changes a little bit now and then, but if you can motivate why it is important, then they should mostly be happy that the specification they have access to better expresses what it actually offers and does.

Comment options

It's a long story but basically yeah, there is an old GWT (yes, Google Web Toolkit) project that is based on these TOs. It is an old Java 8 projects but the Spring project is on Java 21 so almost every new line of code could break everything and it happened too many times already.

Talking about the meta-annotation solution you suggested, I checked that in swagger there is already an annotation aggregator for @parameter called @parameters , so I tried adding multiple @parameter annotations on my method to describe the query parameters and it works. The problem is that I also get the TOs as one of the possible query parameters.
Do you think I can fix that the way I want it ?

openapi: 3.0.1
info:
 title: OpenAPI definition
 version: v0
servers:
- url: http://localhost:8080
 description: Generated server url
paths:
 /product:
 get:
 tags:
 - product-controller
 operationId: getProductTOsByFilter
 parameters:
 - name: filter
 in: query
 required: true
 schema:
 $ref: "#/components/schemas/ProductTO"
 - name: productID
 in: query
 required: true
 schema:
 type: string
 example: "0001"
 - name: productName
 in: query
 schema:
 type: string
 example: My Product
 responses:
 "200":
 description: OK
 content:
 '*/*':
 schema:
 type: array
 items:
 $ref: "#/components/schemas/ProductTO"
components:
 schemas:
 ProductTO:
 type: object
 properties:
 productID:
 type: string
 productName:
 type: string
 weight:
 type: number
 format: float
 description:
 type: string
Comment options

You could try and see if ...(@ModelAttribute @Schema(hidden = true) ProductTO filter)... would properly hide it in the specification

Comment options

It worked !
thanks a bunch for all the help, Mattias
Couldn't make it without your knowledge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /