I am trying to make sense of reactive paradigms, but the logic appears counter to my needs.
The situation is the early stage of a registration process: start with registration data, check if an account exists for the supplied email (getting back either an AccountDto
or null
) and processing from there. With an imperative approach, this is easy; branch on account == null
. But with a reactive paradigm, I can't make sense of it.
If I were processing the account
and substituting something in for the null
case, that would be fine. But in this instance, it's effectively inverted: when I get back null
– i.e. no account exists – I want to do the main processing to create the account, whereas when it is not null
, I want to use the error-equivalent fallback.
The only approach I've found that will work is first use an imperative branching to wrap reactive elements, per:
public ResponseDto registerAccount (RegistrationDto data)
ResponseDto responseDto = new ResponseDto ();
if (accountExists(data.getEmail()) {
// return responseDto with account-exists error messaging
} else {
// create the account, send verification email, etc
// return responseDto with information that verification is sent
}
}
public boolean accountExists (String email) {
return retrieveAccount(email)
.hasElement().block();
}
public Mono<AccountDto> retrieveAccount (String email) {
// calls db service; returns either the Mono-wrapped AccountDto or Mono-wrapped null.
}
Given that I am being pushed down the reactive path, I would rather avoid this hybrid approach.
How do I process the result where the main body of processing depends on the Mono
being empty and the equivalent of an error state is when it has contents to process?
CodePudding user response:
You are just one flatMap
away from the reactive path:
public Mono<ResponseDto> registerAccount(RegistrationDto data) {
return retrieveAccount(data.getEmail())
.hasElement()
.flatMap(accountExists -> {
if (accountExists) {
// return responseDto with account-exists error messaging
} else {
return createAccount(data);
}
});
}
public Mono<AccountDto> retrieveAccount(String email) {
// calls db service; returns either the Mono-wrapped AccountDto or Mono-wrapped null.
}
private Mono<ResponseDto> createAccount(RegistrationDto data) {
// create the account, send verification email, etc
// return responseDto with information that verification is sent
}
CodePudding user response:
Consider reading content of those links:
- https://projectreactor.io/docs/core/release/reference/#about-doc
- Correct way of throwing exceptions with Reactor
- https://projectreactor.io/docs/core/release/reference/#_fallback_method
First page is a link to reactor user guide.
Second page is about recomendation for handling errors in reactor world.
Third page is just my tip how to resume after error.