In a traditional web application it is easy to validate the request body in the controller method, eg.
ResponseEntity create(@Valid @ResponseBody Post post)
One of the ways I've managed to do it in my application is the following (code is in Kotlin but the idea is the same). I've declared RequestHandler
class which performs validation:
@Component
class RequestHandler(private val validator: Validator) {
fun withValidBody(
block: (Mono) -> Mono,
request: ServerRequest, bodyClass: Class): Mono {
return request
.bodyToMono(bodyClass)
.flatMap { body ->
val violations = validator.validate(body)
if (violations.isEmpty())
block.invoke(Mono.just(body))
else
throw ConstraintViolationException(violations)
}
}
}
Request objects can contain java validation annotations in this way:
data class TokenRequest constructor(@get:NotBlank val accessToken: String) {
constructor() : this("")
}
And handler classes use RequestHandler
to perform validation:
fun process(request: ServerRequest): Mono {
return requestHandler.withValidBody({
tokenRequest -> tokenRequest
.flatMap { token -> tokenService.process(token.accessToken) }
.map { result -> TokenResponse(result) }
.flatMap { ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(Mono.just(it), TokenResponse::class.java)
}
}, request, TokenRequest::class.java)
}
Got the idea from this blog post.