I'm creating the swagger file for the documentation of the various APi. In a controller I have the case where I request a RequestParam and a RequestBody:
@PostMapping("/message-now/save-with-params")
@Timed(value = MetricsTimerConstants.storeMessageWithParamsTimer)
public ResponseEntity<Object> saveMessageWithParams(@RequestBody Map<String, Object> request,
@RequestParam List<String> params) { .....
Is there a way to define Lists and Maps in OpenApi? searching I found nothing on this subject
Well , to answer your question in detail let me first make you understand how lists and maps work in OpenAPI
, though they may not look straight forward and documented that clearly in the documentation by naming , but they do exist .
1. Lists
Lists are nothing but basically arrays . So
OpenAPI
does provide parameter input of typequery
to support that . While stating the type of parameter , you also need to specifydata-type
of the parameter as shown below to make it work .
As , shown above , you need to define items
section where you define type of the elements in the list , in your case , it is a list of strings . So , if you generate a client code for this definition , you will see that it generates a list of strings in the api definition as below .
As you can see , it gets generated as a @RequestParam
type of input value . So , you may understand now that lists do exists in the OpenAPI
definition in this manner .
2. Maps
For maps as well , they are documented popularly as
dictionary
in theOpenAPI
documentation which is same thing as a JavaHashMap
. InOpenAPI
, we can make use of theadditionalProperties
attribute while defining a model in the spec . For example , you want a request body as a HashMap in your Rest API , i.e
@RequestBody Map<String, Object> request
To make this work , you will write your OpenAPI specification something like as below :
Note: Above Request model that we created , should be used in the ref section of API endpoint as a "body" input type parameter as shown below .
Verification :
Now , let's verify that the OpenAPI definition model that we created above, will get translated into a HashMap , when the code is generated . So , lets generate a Spring based Server Code by going to https://editor.swagger.io/ , then after creating your API definition go to
Generate Server > spring
. It will generate a Spring based API code based on the API definition that you would have created for your use-case . So , if you go to that zip file and look insidesrc/main/java/io/swagger/api
, there will a file named as<YOUR_API_NAME>Api.java
(In my case , just to test your scenario, i edited the default Pet API provided by swagger automatically on https://editor.swagger.io/ , so in my case file name wasPetApi.java
) . So , when i looked at the generated code for the API endpoint that requires a "request" map to receive the request , it was like below .
Now , you may think why its just @RequestBody Request request
and not @RequestBody HashMap<String,Object> request
right ? But let me tell you , its a HashMap only and not an object !! But how ?? . To answer that question , i went to following location in the generated source code folder at path src/main/java/io/swagger/model
and looked for a file called Request.java
(In your case your file name may differ based upon what you name your map in your OpenAPI spec , in my case i had named it as Request) . Basically swagger keeps all generated models defined in OpenAPI spec at this location . So , looking at the Request.java model class , i found this at the class level declaration .
So, by now you would have understood that the generated model class is extending the Map of type HashMap<String,Object>
, so basically Request
is a HashMap
as it extends the HashMap<String,Object>
, exactly what you desired for . Just to make things , more clear just see below image , where i tried to invoke a map based method on the Request
object and it's working , as my IDE is giving suggestions for HashMap
related methods indicating that it is indeed a HashMap !!
Conclusion:
So , We can easily deduce that HashMaps (aka dictionaries) and Lists (aka arrays) are available in the
OpenAPI
spec for designing data-models so that when you generate them you can convert them to corresponding data structures as shown above by digging in the documentation deeper . You can read more about them by going at following links :
https://swagger.io/docs/specification/data-models/dictionaries/ https://swagger.io/docs/specification/describing-parameters/
Hope that helps !! :)