Home > Blockchain >  Spring Boot Reactive - register user
Spring Boot Reactive - register user

Time:04-02

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

  • Related