'SpringDoc for a complex response type
I am documenting an existing Java based API using SpringDoc. There is a common response object for all of our APIs (shown below) which has two fields, a status and an object containing the actual result.
class MyResponse {
private String status;
private Object result;
.........
}
Is there a way to allow me to document the actual runtime type of the result object depending on the API that is called? e.g. if my call is to the getCustomer() API, I wish to generate documentation for a Customer result object, and if my call is to the getProduct() API, I wish to generate documentation for a Product result object.
Solution 1:[1]
You should use the @ApiResponse to document the type of data that will be returned. Following are the annotations of your interest -
@ApiResponses- Represents the array of responses a method might return, including error responses. The common set of responses can be specified at the class level while the specific once can be provided at the method level.value- An array of@ApiResponse.
@ApiResponse- Used to describe a specific response that a method might return. Can not be used at the class level.responseCode- AStringvalue representing the response code, such as"200","401"etc.description- Description of the response. Usually the HTTP Status Message, such as"OK","Unauthorized"etc.content- Describes the content that will be returned by the method. Refer the@Contentannotation for details.
Important - Responses such as
401 - Unauthorizedmay not return anything. In such cases, content should be initialed as an empty@Schemaas shown below.@ApiResponse(responseCode = "401", description = "Unauthorized", content = {@Content(schema = @Schema())})@Content- Describes the content that will be returned as a response by the method.mediaType- Specifies the type of object that will be returned by the API. Mandatory to be specified, if a valid response is returned. Can be defined at the class level. Examplesapplication/jsonortext/plainetc.schema- The@Schemaobject that will be returned as a response from the method. Refer@Schemafor more details.
@Schema- Describes the schema object (POJO or can even be a primitive datatype, set themediaTypeaccordingly) that will be returned as a response. Not specifying any attributes means nothing will be returned from the object (often used with error responses).implementation- Name of the class object that will be returned as a response from the method. Defaults toVoid.class
@Parameter- Used at the method parameters with other annotations such as@RequestParam,@PathVariableetc.description- Describes the parameter that is expected.required-Booleanvalue specifying if the parameter is optional or mandatory. Defaults to the one specified by the parameter such as@RequestParam,@PathVariableetc.
@io.swagger.v3.oas.annotations.parameters.RequestBody- Describes the request body expected by the method handling the request.description- Provides a description for the Request Body.required-Booleanvalue specifying if the body is optional or mandatory. Defaults totrue.
Remember
- Although
@Parametercan also be used instead of this, in that case, all the class obejcts are resolved by reference, thus only the one described last is retained. - This
@RequestBodyis different from the one provided by the Spring, and thus must be used along with the@org.springframework.web.bind.annotation.RequestBody
Below is an example of a controller with the required annotations for documentation.
@RestController
// the "produces" attribute in @RequestMapping can be used to specify the default mediaType.
@RequestMapping(path = "/api/v1/user/", produces = { MediaType.APPLICATION_JSON_VALUE })
// Defines common tag for all the operartions handled by this class
@Tag(name = "User Operations", description = "APIs for operation on User")
// API responses that might be returned by all the methods in this class
@ApiResponses(value = {
@ApiResponse(responseCode = "400", description = "Bad Request", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserErrorResponse.class))}),
@ApiResponse(responseCode = "500", description = "Internal Server Error", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserErrorResponse.class))})
})
public class UserController {
// POST Method
// Swagger Annotations
@Operation(summary = "Create User", description = "User-ID is generated and maintained by the service.", tags = {"User Operations"})
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "Created", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = UserCreateResponse.class))}),
@ApiResponse(responseCode = "409", description = "User Collision Detected", content = {@Content(schema = @Schema())})
})
// Spring Annotations
@ResponseStatus(code = HttpStatus.CREATED)
@PostMapping(value = "/patients", consumes = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<MyResponse> createUser(
// Note the two @RequestBody from Swagger and Spring
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "A request to create user object") @Valid @RequestBody final User user)
{
...
}
// GET Method
// Swagger Annotations
@ApiResponses(value = {
@ApiResponse(
responseCode = "200", description = "OK",
// Note the way content is defined for valid objects
content = {@Content(mediaType = "application/json", schema = @Schema(implementation = User.class))})),
@ApiResponse(
responseCode = "404", description = "Not Found",
// Note the way, when no object is returned
content = {@Content(schema = @Schema())})),
})
// Spring Annotations
@ResponseStatus(HttpStatus.OK)
@GetMapping(value = "")
public MyResponse getUser(
@Parameter(required = false, description = "Search by firstName") @RequestParam(required = false) String firstName)
{
...
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Debargha Roy |
