Search code examples
spring-bootspring-webfluxreactive

Proper way to chain multiple related db ( repository calls )


Using Spring WebFlux and ReactiveCrudRepository

Assume we have

UserRepository, UserDetailsRepository, UserTransactionRepository

I want to find the user, find their details and their transaction and return a single DTO object. Separate calls would look lik

userRepo.findById
userDetailsRepo.findByUserId
userTransactionRepo.findByUserId

How id properly chain them?

userRepo.findById()
.map( u -> userDetails.findByUserId( u ))
.map( ud -> userTrans.findByUserId( u))
.map( data -> process....);

?


Solution

  • In ReactiveCrudRepository, the findById method returns Mono from the emitted entity. You must use flatMap().

    return userRepo.findById(id)
                    .switchIfEmpty(Mono.error(new UserNotFoundException("User not found")))
                     .zipWhen(u -> userDetails.findById(u))
                      .zipWhen(ud -> userTrans.findById(ud))
                       .map(tuple -> mapper(tuple.getT1().getT1(), tuple.getT1().getT2(), tuple.getT2()));
    

    https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/reactive/ReactiveCrudRepository.html