Reputation: 71
I have a controller with a @RequestBody
DTO. I need to show the DTO's schema instead of the default string
in the RequestBody Schema in Swagger.
By using @Operation above the API and @Parameter within, I've been able to describe the DTO in two places
and fill in the example (see code). I've tried @Schema
in the @Operation
(under requestBody) and @Parameter
annotations. The former throws an NPE and the latter changes nothing, with a variety of tries regarding counterpart annotations in the DTO itself.
Sample Controller
@RequestMapping(value = "/{myPathVar}", method = RequestMethod.POST)
@Operation(summary = "Create something.",
parameters = { @Parameter(in = ParameterIn.PATH, name = "myPathVar", description = "Some path variable. Swagger uses this description.") },
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "My description here.",
content = @Content(examples = @ExampleObject("{\"A\" : \"a\",\"B\" : \"{\"b\" : \"foo\", \"bb\" : \"bar\"}"))))
@ApiResponse(content = @Content(schema = @Schema(implementation = MyReturningType.class)))
public MyReturningType doSomethingCool(
@Parameter(description = "Some description Swagger ignores.", example = "123") @PathVariable(value = "myPathVar") int myPathVar,
@Parameter(description = "My other description here.", schema = @Schema(implementation = MyDto.class)) @RequestBody MyDto dto) {
// do something cool
}
Sample DTO
// Do I need certain annotations here?
public class MyDto {
// What annotation goes here? @Parameter, @JsonProperty, @Schema, something else?
private int someInt;
private String someString;
private Object someObject;
}
What combination of annotations do I need to correctly label the DTO Schema within the DTO and then reference this Schema from the controller such that the Schema field is populated in SwaggerUI?
Upvotes: 7
Views: 21980
Reputation: 91
Annotated your dto like the following. It works for me
@Schema(description = "User Dto")
@Data
public class UserDto {
private int id;
@JsonProperty
private String email;
@JsonProperty
private String password;
@JsonProperty
private String firstName;
@JsonProperty
@Schema(description = "User Id")
private String lastName;
}
Upvotes: 1
Reputation: 2708
The issue might have been caused by the fact that the fields in your DTO are of private visibility and from the code you shared, doesn't look like they have getters and setters available.
Refer to the below example for a working example of how it can be done
Controller
// Using the specific mapping annotation will keep the code clean
@PostMapping("/{myPathVar}")
// The below annotation describes the operation
@Operation(
summary = "Brief description of the operation",
description = "Detailed description of the operation")
// Describe the possible responses next. Prefer using @ApiResponses for multiple response
@ApiResponse(
// specify the http response code
responseCode = "201",
// some description. Maybe use the corresponding http response code's description
description = "Created",
// describe the content that will be returned for this response code
content = @Content(
// optionally, specify the media type for the response here as shown in the below code
mediaType = MediaType.APPLICATION_JSON_VALUE,
// specify the implementation of the response DTO here
schema = @Schema(implementation = Void.class)))
public Void doSomethingCool(
// Use @Parameter for @PathVariable and @RequestVariable
@Parameter(description = "Description for path/request-parameter here")
@PathVariable(value = "myPathVar")
int myPathVar,
// Both these @RequestBody annotations are mandatory.
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "Controller-level model description here")
@org.springframework.web.bind.annotation.RequestBody
TestDTO dto) {
// ... do some cool stuff here
return null;
}
DTO
@Schema(description = "Model-level description here")
public class TestDTO {
@Schema(description = "Field-level description here")
private int someInt;
@Schema(description = "Another Field-level description here")
private String someString;
@Schema(description = "Yet another Field-level description here")
private Object someObject;
// all getters and setters here
}
This gives you the output as below
Upvotes: 4