Search code examples
javamethod-chainingspring-reactor

Using Spring Reactor Mono with multiple switchIfEmpty


I had a simple java validation flow like this example:


if (!request.isValid()) {
    throw new ValidationException("Its not valid");
}

if (!request.isCorrect()) {
    throw new IncorrectException();
}

return Mono.just(
        someService.process(request)
);

I tried to chain method calls to get rid of ifs but this does not work:

return Mono.just(request)
        .filter(req -> !req.isValid())
        .switchIfEmpty(Mono.error(new ValidationException("Its not valid")))
        .filter(req -> !req.isCorrect())
        .switchIfEmpty(Mono.error(new IncorrectException()))
        .flatMap(req -> Mono.just(someService.process(req)));

The problem is, even if it fails on isValid() the code goes on and the second switch overwrites the first one.

How could I make the code working and retain the chaining?


Solution

  • Have you tried to use "Mono.defer()"?

    Your code would be something like:

    return Mono.just(request)
                .filter(req -> !req.isValid())
                .switchIfEmpty(Mono.defer(() -> Mono.error(new ValidationException("Its not valid"))))
                .filter(req -> !req.isCorrect())
                .switchIfEmpty(Mono.defer(() -> Mono.error(new IncorrectException())))
                .flatMap(req -> Mono.just(someService.process(req)));
    

    I had the same issue, and it worked for me.

    You can read more about Mono.defer() on this thread:

    what does Mono.defer() do?