-
-
Notifications
You must be signed in to change notification settings - Fork 545
Add QueryString documentation when using TransferObject with @ModelAttribute as single argument #3029
-
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
Beta Was this translation helpful? Give feedback.
All reactions
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
-
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).
Beta Was this translation helpful? Give feedback.
All reactions
-
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
Beta Was this translation helpful? Give feedback.
All reactions
-
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.
Beta Was this translation helpful? Give feedback.
All reactions
-
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.
Beta Was this translation helpful? Give feedback.
All reactions
-
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
Beta Was this translation helpful? Give feedback.
All reactions
-
You could try and see if ...(@ModelAttribute @Schema(hidden = true) ProductTO filter)...
would properly hide it in the specification
Beta Was this translation helpful? Give feedback.
All reactions
-
It worked !
thanks a bunch for all the help, Mattias
Couldn't make it without your knowledge
Beta Was this translation helpful? Give feedback.
All reactions
-
🎉 1