So the app flow is like:
This is the webclient which I am using(replica):
public Mono<Details> someRestCall(String name) {
return this.webClient.get().url("/{id}/details", name)
.retrieve().bodyToMono(Details.class);
}
Now I don't want to return this Mono object directly to the client(like the Angular app) via the controller, since this is an intermediary step. I want to run few validations on the response received from the WebClient.
I have tried the .block()
method to retrieve the function but it seems to be a bad practice as per the reactive programming. (blocking op)
Also, I am unable to understand how to use the .subscribe()
method to retrieve the response object and run validation/checks on it and return True
if the validation passes.
In simple terms, instead of returning a Mono object from my module/validation code, I want to return a normal boolean value/Java object.
I am new to reactive programming, can anyone please help me get this resolved?
With a little effort you can use JSR-303 annotation based validation on the POJOs that are returned by a WebClient call. Here's a minimal example:
@Component
public class MyClass {
final Validator validator;
MyClass(Validator validator) {
this.validator = validator;
}
<T> T validate(T obj) {
Set<ConstraintViolation<T>> violations = this.validator.validate(obj);
if (violations.size() > 0) {
throw new ResponseStatusException(INTERNAL_SERVER_ERROR, violations.toString());
}
return obj;
}
public Mono<Details> someRestCall(String name) {
return this.webClient.get()
.url("/{id}/details", name)
.retrieve()
.bodyToMono(Details.class)
.doOnNext(this::validate);
}
}
In practice you might want a better formatted violations string and if validation is done in a few places then you could lift that logic into its own class.