0
votes

I am trying to do a nested calls to database, using spring webflux/reactor, to return a Mono of nested objects (a User with his Roles).

The scenario is as following:

  • retrieve a user row having a username from database;
  • map the user row to User POJO;
  • retrieve roles of the user by user id;
  • map roles to List of Roles;
  • set the mapped roles to User POJO;
  • return a Mono of User.

The scenario above have to be done without blocking (I know that the mapping is a so little blocking :) ).

public Mono<User> retrieveByUsername(String username)  {
    return databaseClient.execute(usersQueries.getProperty("users.select.by.username"))
            .bind("username", username.toLowerCase())
            .map((row, meta) -> UserRowMapper.mapRow(row, meta))
            // here goes nested database query to retrieve roles and set them to retrieved user 
            // and return Mono<User>
            .one();
}

Thank you in advance for your help.

1
Use flatmap, then do your next callToerktumlare

1 Answers

1
votes

Here is how I see a solution for your question:

public Mono<User> retrieveByUsername(String username) {
    Mono<User> userMono = databaseClient
            .execute(usersQueries.getProperty("users.select.by.username"))
            .<User>map((row, meta) -> UserRowMapper.mapRow(row, meta))
            .one()
            .cache();

    Flux<Role> roles = Mono
            .from(userMono)
            .flatMapMany(user -> databaseClient
                    .execute(usersQueries.getProperty("roles.select.by.user.id"))
                    .bind("userId", user.getId())
                    .<Role>map((row, meta) -> RoleRowMapper.mapRow(row, meta))
                    .all()
            );

    return Mono
            .from(userMono)
            .flatMap(user -> roles
                    .collectList()
                    .map(r -> {
                        user.setRoles(r);
                        return user;
                    })
            );
}