I have a spring (boot) server and want to generate the OpenAPI spec from the annotations with springdoc.
I have a request with two parameters in the request body. I want the first to be required and the second to be optional.
@RequestBody(required = {true|false})
seems to only set all parameters in the body to (not) required.
The Javadoc for @Parameter
on the other hand say to use io.swagger.v3.oas.annotations.parameters.RequestBody
This is my code that I would expect to generate a spec where the first parameter is required and the second one is optional:
@GetMapping("/fstVector")
public ResponseEntity<Vector> fstV(@RequestBody final Vector v1, @RequestBody(required = false) final Vector v2) {
return new ResponseEntity<>(v1, HttpStatus.OK);
}
@PostMapping("/fstVector")
public ResponseEntity<Vector> fstVPost(@RequestBody(required = true) final Vector v1, @RequestBody(required = false) final Vector v2) {
return new ResponseEntity<>(v1, HttpStatus.OK);
}
The generated spec however has both parameters required:
/pond/fstVector:
get:
tags:
- circle-escape-controller
operationId: fstV
parameters:
- name: v1
in: query
required: true
schema:
$ref: '#/components/schemas/Vector'
- name: v2
in: query
required: true
schema:
$ref: '#/components/schemas/Vector'
responses:
"200":
description: OK
content:
'*/*':
schema:
$ref: '#/components/schemas/Vector'
post:
tags:
- circle-escape-controller
operationId: fstVPost
requestBody:
content:
application/json:
schema:
type: object
properties:
v1:
$ref: '#/components/schemas/Vector'
v2:
$ref: '#/components/schemas/Vector'
required: true
responses:
"200":
description: OK
content:
'*/*':
schema:
$ref: '#/components/schemas/Vector'
How can I require only a specific parameter for all four request types?
Important
@RequestBody
annotations. One from the Spring framework org.springframework.web.bind.annotation.RequestBody
and another from io.swagger.v3.oas.annotations.parameters.RequestBody
Importantly, even when you use the io.swagger.v3.oas.annotations.parameters.RequestBody
from the Swagger library, you'll still need to use the org.springframework.web.bind.annotation.RequestBody
to receive the actual object.
Refactoring the code as below should be helpful in your case
Controller Class
@GetMapping("/fstVector")
public ResponseEntity<Vector> fstV(
// we generally use @RequestParam for query parameters. Query parameters are generally optional and thus the "required" attribute of @Parameter defaults to "false"
@Parameter @RequestParam final Vector v1,
// set @Parameter to TRUE if the parameter must be passed.
@Parameter(required = true) @RequestParam final Vector v2
) {
return new ResponseEntity<>(v1, HttpStatus.OK);
}
@PostMapping("/fstVector")
public ResponseEntity<Vector> fstVPost(
// RequestBody objects are "required" by default. To make them optional, add "(required = false)"
@org.springframework.web.bind.annotation.RequestBody // Spring
@io.swagger.v3.oas.annotations.parameters.RequestBody // Swagger
@Valid // Bean validation to ensure if the incoming object is valid
final Vector v1
) {
return new ResponseEntity<>(v1, HttpStatus.OK);
}
For domain object, refactor the DTO as below
DTO
@Schema(description = "My DTO")
class Vector {
// The below attribute is required
@NotNull
@Parameter(description = "my first attribute", required = true)
String attribute1;
// The below attribute is optional
@Parameter(description = "my second attribute", required = false)
String attribute2;
}