【问题标题】:How to map several Mono into one object using Spring Webflux Reactive Java?如何使用 Spring Webflux Reactive Java 将多个 Mono 映射到一个对象中?
【发布时间】:2021-06-17 07:27:45
【问题描述】:

我想知道哪种是将多个响应式服务响应映射或合并到一个唯一对象中的正确或最佳方法。

例如,简单的传统代码如下:

public UserProfile getUserProfile(String id){
    User user = userService.getUser(id);
    Messages messages = messageService.getMessagesFromUser(id);
    Notifications notifications = notificationService.getNotificationsForUser(id);
    return new UserProfile(user, message, notifications);
}

当尝试使用 webflux 编写更“功能性”时,它看起来像这样:

public Mono<UserProfile> getUserProfile(String id){
   return userService.getUser(id)
          .map( user -> {
                return messageService.getMessagesFromUser(id)
                     .map(messages -> {
                           return notificationService.getNotificationsForUser(id)
                                  .map(notifications -> new UserProfile(user, message, notifications))
                       }
            }
}

我个人不喜欢这种“地图步骤”,因为它不是顺序转换。我需要更多类似并行处理,使用 CompletableFuture 或其他多线程框架和传统命令式代码(非函数式)非常容易实现。

您认为您可以如何改进此实施? 这段代码运行良好,但我认为这不是正确的编写方式。在我看来,它看起来很丑,不太好理解。

编辑!!! 我想我找到了使用 Mono.zip 的更好方法,但我认为它应该可以改进

@GetMapping("v1/event/validate/")
public Mono<PanoramixScoreDetailDTO> validateEvent(@RequestBody LeadEventDTO eventDTO) {
    return leadService.getLead(eventDTO.getSiteId(), eventDTO.getIdContacto())
            .flatMap(lead -> {
                Mono<PhoneValidationDTO> phoneValidation = validationService.validatePhone(eventDTO.getSiteId(), lead.getPhone());
                Mono<EmailValidationDTO> emailValidation = validationService.validateEmail(eventDTO.getSiteId(), lead.getLeadUser().getEmail());
                Mono<ProcessedProfileSmartleadDTO> smartleadProfile = smartleadService.getProcessedProfile(eventDTO.getSiteId(), eventDTO.getIdUsuario());
                return Mono.zip(phoneValidation, emailValidation, smartleadProfile)
                        .map(tuple -> panoramixScoreMapper.mapTo(lead, tuple.getT1(), tuple.getT2(), tuple.getT3(), eventDTO));
            });
}

我想听听您的意见。 谢谢!

【问题讨论】:

  • 我知道声明函数 Mono 并返回 UserProfile 是一个错误。我认为这不是问题的重点。真正重要的是将多个 Mono> 对象合并为一个 Mono 的编程风格

标签: java spring-webflux reactive reactor


【解决方案1】:

Mono.zip() 是可行的方法,但您可以通过使用允许一次性指定压缩发布者和地图功能的覆盖来节省一步:

@GetMapping("v1/event/validate/")
public Mono<PanoramixScoreDetailDTO> validateEvent(@RequestBody LeadEventDTO eventDTO) {
    return leadService.getLead(eventDTO.getSiteId(), eventDTO.getIdContacto())
            .flatMap(lead ->
                    Mono.zip(arr ->
                                    panoramixScoreMapper.mapTo(lead, (PhoneValidationDTO) arr[0],
                                            (EmailValidationDTO) arr[1],
                                            (ProcessedProfileSmartLeadDTO) arr[2], eventDTO),
                            validationService.validatePhone(eventDTO.getSiteId(), lead.getPhone()),
                            validationService.validateEmail(eventDTO.getSiteId(), lead.getLeadUser().getEmail()),
                            smartleadService.getProcessedProfile(eventDTO.getSiteId(), eventDTO.getIdUsuario()))

            );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-14
    • 2018-08-24
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    相关资源
    最近更新 更多