I have two methods.
Main method:
@PostMapping("/login")
public Mono<ResponseEntity<ApiResponseLogin>> loginUser(@RequestBody final LoginUser loginUser) {
return socialService.verifyAccount(loginUser)
.flatMap(socialAccountIsValid -> {
if (socialAccountIsValid) {
return this.userService.getUserByEmail(loginUser.getEmail())
.switchIfEmpty(insertUser(loginUser))
.flatMap(foundUser -> updateUser(loginUser, foundUser))
.map(savedUser -> {
String jwts = jwt.createJwts(savedUser.get_id(), savedUser.getFirstName(), "user");
return new ResponseEntity<>(HttpStatus.OK);
});
} else {
return Mono.just(new ResponseEntity<>(HttpStatus.UNAUTHORIZED));
}
});
}
And this invoked method (the service calls an external api):
public Mono<User> getUserByEmail(String email) {
UriComponentsBuilder builder = UriComponentsBuilder
.fromHttpUrl(USER_API_BASE_URI)
.queryParam("email", email);
return this.webClient.get()
.uri(builder.toUriString())
.exchange()
.flatMap(resp -> {
if (Integer.valueOf(404).equals(resp.statusCode().value())) {
return Mono.empty();
} else {
return resp.bodyToMono(User.class);
}
});
}
In the above example, switchIfEmpty()
is always called from the main method, even when a result with Mono.empty()
is returned.
I cannot find a solution for this simple problem.
The following also doesn't work:
Mono.just(null)
Because the method will throw a NullPointerException
.
What I also can't use is the flatMap method to check that foundUser
is null.
Sadly, flatMap doesn't get called at all in case I return Mono.empty()
, so I cannot add a condition here either.
@SimY4
@PostMapping("/login")
public Mono<ResponseEntity<ApiResponseLogin>> loginUser(@RequestBody final LoginUser loginUser) {
userExists = false;
return socialService.verifyAccount(loginUser)
.flatMap(socialAccountIsValid -> {
if (socialAccountIsValid) {
return this.userService.getUserByEmail(loginUser.getEmail())
.flatMap(foundUser -> {
return updateUser(loginUser, foundUser);
})
.switchIfEmpty(Mono.defer(() -> insertUser(loginUser)))
.map(savedUser -> {
String jwts = jwt.createJwts(savedUser.get_id(), savedUser.getFirstName(), "user");
return new ResponseEntity<>(HttpStatus.OK);
});
} else {
return Mono.just(new ResponseEntity<>(HttpStatus.UNAUTHORIZED));
}
});
}
switchIfEmpty() is always called from the main method, even when a result with Mono.empty() is returned.
. It is meant to be called isnt it ? – Alpestrinenull
from the service layer which can be handled by the main method. I guess I could throw an error too, but prefer not to. The 404 should be handled on the service layer, and when a user is not found, this is application logic which I feel I should handle withif
, and not by exception handling. I'm going to reviewswitfhIfEmpty
in the docs. Still, a working suggestion? – FaughMono.empty()
which is going to callswitchIfEmpty
. Anyways if you want to handle errors if that is what you are looking for then you can useonErrorResume()
and handle appropriately or you can also useonErrorReturn()
. guide – AlpestrineinsertUser
method inswitchIfEmpty
gets called before the flatMap method handling the 404 gets called. No idea why this is the case. – Faugh