Reactive programming is kind of hard to understand for me. My use case - I would like to register a user (save it to DB) only in case the user with the given email doesn't exist in DB. I have a function in Kotlin in a Spring Boot service:
fun registerUser2(userDto: UserDto): Mono<PersonalUser> {
return personalUserRepository.findByEmail(userDto.email!!)
.switchIfEmpty(
personalUserRepository.save(toEntity(userDto))
).flatMap {
Mono.empty()
}
}
Then in the Controller I want to react on an empty Mono
to distinguish between
- user was created, and
- user cannot be created if it already exists.
@PostMapping("/reg")
fun register(@RequestBody user: UserDto): Mono<ResponseEntity<String>> {
return userService2.registerUser2(user)
.flatMap { Mono.just(ResponseEntity("User[username: ${it!!.username}, password: you cant see me, email: ${it.email}, first name: ${it.firstName}, last name: ${it.lastName}]", HttpStatus.CREATED)) }
.switchIfEmpty(Mono.just(ResponseEntity("User with this email already exist", HttpStatus.FOUND)))
}
Repository method is
fun findByEmail(email: String): Mono<PersonalUser>
Saving is working. So it saves first time. Second time not. But I am getting always Mono.empty()
and therefore all the time HttpStatus.FOUND
. It looks like switchIfEmpty
is not like an if statement and therefore it continues to flatMap
. I tried many changes, but it is still not working. Any help is appreciated.
CodePudding user response:
Ofcourse if you call
.flatMap {
Mono.empty()
}
it will always return an empty mono.
I would try something like
personalUserRepository.findByEmail(userDto.email!!)
.flatMap{Mono.error()}
.switchIfEmpty(
personalUserRepository.save(toEntity(userDto))
)
so if the user is found, it return an error, if not it creates the user, because the flatMap
after findByEmail
would be executed at subscribtion time only if the mono returned by findByEmail
is not empty.
CodePudding user response:
Thanks @shy-albatross, yeah, it was strategy I was trying but explicitly like when findByEmail
is empty throw my RuntimeException etc.
Final solution so easy, but really it took me days.
fun registerUser(userDto: UserDto): Mono<PersonalUser> {
return personalUserRepository.save(toEntity(userDto))
.onErrorResume { Mono.empty() }
}
Plus that UNIQUE
constraint.
Thanks