Skip to content
Advertisement

Spring boot WebFlux : How to write Mono.map() return value?

//Entity
class User{
    rivate Long id;
    private Sting name;
}
class Role{
    private Integer id;
    private String name;
}
class Permission{
    private Integer id;
    private String name;
    private String uri;
}
//Dto
class RoleDto extends Role{   
    private List<Permission> permissions;
}
class UserDto extends User{
    private List<RoleDto> roles;
}

//Service functions
public Mono<SysUser> getUserById(Long userId){
    return userRepository.findSysUserById(userId);
}

public Mono<UserDto> getUserInfoByUserId(Long userId){
    return getUserById(userId).map(user -> {
        UserDto userDto = new UserDto(user);
        roleService.getRolesByUserId(userId).map(roles -> {
            roles.forEach(role -> {
                RoleDto roleDto = new RoleDto(role);
                permissionService.getPermissionsByRoleId(role.getId()).map(plist ->{
                    roleDto.setPermissions(plist);
                    userDto.addRoles(roleDto);
                    return Mono.just(roleDto);//1 Here how to write
                }).subscribe();
            });
            return Mono.just(roles);//2 Here how to write
        }).subscribe();
        return Mono.just(userDto); //3 Here how to write
    });
}

Exception is :

Required type: Mono Provided:Mono no instance(s) of type variable(s) T exist so that Mono conforms to UserDto inference variable R has incompatible bounds: equality constraints: UserDto lower bounds: Mono

How to write function getUserInfoByUserId ?

Advertisement

Answer

Assuming that you are always returning Mono from your repository methods, you can do this

class DoStuff {
  Mono<User> getUserById(Long userId){
    return Mono.just(new User(1L, "test"));
  }

  Mono<List<Role>> getRolesByUserId(Long userId) {
    return Mono.just(Arrays.asList(new Role(1, "guest")));
  }

  Mono<List<Permission>> getPermissionsByRoleId(Integer roleId) {
    return Mono.just(Arrays.asList(new Permission(1, "read", "http://some-url")));
  }

  public Mono<UserDto> getUserInfoByUserId(Long userId){
    return getUserById(userId)
        .flatMap(user -> getRolesByUserId(userId)
            .flatMap(roles -> Flux.fromIterable(roles)
                .flatMap(role -> getPermissionsByRoleId(role.id)
                    .map(p -> new RoleDto(role, p)))
                .collectList()
                .map(roleDtos -> new UserDto(user, roleDtos))
            )
        );
  }
}

I would recommend you to start using immutable java objects since you are dealing with webflux streams. It makes life a lot easy.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement