Hello !
I’m trying to update our code to follow the deprecation of annotation @Valid at container level. It works well in most situations, but in one the validation changed behavior.
I have an interface EventsControllerApi for defining a Spring controller using WebFlux. One endpoint takes a list of DTO as an argument, and both the list and the elements of the list are currently annotated with @Valid. It’s implemented by a class EventsController annotated with @RestController. I have a test checking that if a required attribute of one element is missing in the payload, the endpoint returns a 400.
When I remove the @Valid on the list, the test fails because it now returns a 500. I found a way to generate again the 400 by adding @Validated on the controller interface and defining an ErrorHandler for ConstraintViolationException (before it was probably going through the handler for HttpMessageNotReadableException). Both modifications are needed.
Is there a reason for this change of behavior?
public interface EventsControllerApi {
@Operation(summary = "Get events related to various resources.")
@PostMapping(
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
List<ResourceDto> getEventsByResources(
@PathVariable("organization-id") String organizationId,
@RequestBody @Valid List<@NotNull @Valid ResourceIdRequestDto> resourceIds);
@Schema(description = "a uuid with context from its domain")
@Valid
public record ResourceIdRequestDto(
@JsonProperty("domain")
@NotBlank
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
String domain,
@JsonProperty("type")
@NotBlank
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
String type,
@JsonProperty("id") @NotNull UUID id) {}
class EventsControllerConsistencyTest {
@Autowired WebTestClient webTestClient;
@Test
void shouldReturn400WhenIdIsNull() {
webTestClient
.post()
.uri("/organizations/{organizationId}/events", "organization")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(
"""
[
{
"domain": "domain",
"type": "event"
}
]
""")
.exchange()
.expectStatus()
.isBadRequest();
}