I am trying to create springdoc
swagger documentation, and I would like to represent a request body having data type Map<String, Object>
in a better readable way for clients. But when I declare @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(schema = @Schema(implementation = Map.class)
the Schema is coming as String
(attached the screenshot below)
Method declaration
@Operation(
security = {@SecurityRequirement(name = "bearer-key")},
summary = "Create Data",
operationId = "createData",
description = "Create createData for the **`type`**. "
)
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "Data created",
content = @Content(
schema = @Schema(implementation = Map.class),
examples = {
@ExampleObject(
value = "{\n" +
" \"id\": \"927d810c-3ac5-4584-ba58-7c11befabf54\",\n" +
"}"
)
}
)
),
@ApiResponse(
responseCode = "400",
description = "BAD Request")
}
)
@PostMapping(
value = "/data/type",
produces = APPLICATION_JSON_VALUE,
consumes = APPLICATION_JSON_VALUE
)
@io.swagger.v3.oas.annotations.parameters.RequestBody(
content = @Content(
schema = @Schema(implementation = Map.class),
examples = {
@ExampleObject(
value = "{\n" +
" \"label\":\"tourism\",\n" +
" \"location\":\"France\"\n" +
" }"
)
}
)
)
ResponseEntity<Map<String, Object>> createData(
@Parameter(name = "type", required = true)
@PathVariable("type")
String type,
@Parameter(name = "request payload")
@Valid
@RequestBody
Map<String, Object> body
);
Though the Spring boot automatically infers the type based on the method signature, it is not clear for the data type Map
. For instance, by default, the type Map<String, Object> will be inferred as below
But I would like to show the Schema in a more understandable way for the client who refers to my API. I could see there is a closed ticket without a proper solution in Github. As per my requirement, the request body should be a type agnostic and dynamic key-value pairs, so there is no other way apart from receiving the request as Map<String, Object>
. has anyone implemented a better way with type Map
rather than creating a custom request/response model?
Sharing my working approach for the issue, I have done a workaround for the @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(schema = @Schema(implementation = Map.class)
the Schema is coming as String issue.
I have declared a custom schema called Map in the OpenAPI bean declaration as below
new OpenAPI()
.components(new Components()
.addSchemas("Map", new Schema<Map<String, Object>>().addProperties("< * >", new ObjectSchema())
))
.....
.....
and used the above schema in the Schema declaration as below
@io.swagger.v3.oas.annotations.parameters.RequestBody(
content = @Content(mediaType = APPLICATION_JSON_VALUE,
schema = @Schema(ref = "#/components/schemas/Map"))
The above approach can be used in the place of ApiResponse
also as below
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200",
content = @Content(mediaType = APPLICATION_JSON_VALUE,
schema = @Schema(ref = "#/components/schemas/Map"))
Note: If we use the above custom schema approach, we don't need to alter or ignore any of the types which SpringDoc
is using internally.