如何在反应函数中使用条件和多个步骤

How to use condition and multiple steps in a reactive function

我目前正在使用 kotlin quarkus 和 mutiny 构建反应式应用程序,作为反应式编程的新手,我想知道处理以下工作流程的最佳方式是什么:

这是我现在的代码:

fun createCard(creationOrder: CreationOrder): Uni<CardCreationResult> {
    return creationOrdersRepository.findByOrderId(creationOrder.orderId)
        .onItem().transform {item ->
            if (item != null) {
                CardCreationResult.AlreadyCreated
            } else {
                creationOrdersRepository.save(creationOrder)

                //TODO external webservice call
                
                val cardNumber = UUID.randomUUID().toString()
                creationOrdersRepository.updateCardNumberAndStatus(externalServiceCallResult)
                CardCreationResult.Created
            }
        }
}

此方法最终将由休息端点调用。

creationOrdersRepository.savecreationOrdersRepository.updateCardNumberAndStatus return 是一个 CompletableFuture(我使用的是 quarkus amazon dynamodb 客户端)。

这样做正确吗?我应该将保存和 updateCardNumberAndStatus 结果包装在 Uni 中吗(我一直在尝试但一直出现类型错误)?

我认为您的代码没有达到您的预期。如果我理解正确,您需要在发出结果之前“保存”和“更新”。所以,你需要类似的东西(在 Java 中,因为我的 Kotlin 不是很好):

return creationOrdersRepository.findByOrderId(creationOrder.orderId)
  // We will be returning a Uni as the save, update and the web service are 
  // async
  .onItem().transformToUni(item -> {
    if (item != null) {
      return Uni.createFrom().item(CardCreationResult.AlreadyCreated);
    } else {
      // Create an Uni from the save operation
      Uni<Void> save = Uni.createFrom().completionStage(() -> 
        creationOrdersRepository.save(creationOrder));
      // This uni represents the invocation of the remote service
      Uni<String> webService = callWebService();

      // we chain the operations save -> web service -> update -> Created
      return save
        .chain(webService)
        .chain(externalServiceCallResult -> 
          Uni.createFrom().completionStage(() -> creationOrdersRepository
                  .updateCardNumberAndStatus(externalServiceCallResult)
        )        
        .replaceWith(CardCreationResult.Created);
    }