project reactor - WebFlux chain various actions based on different results - Stack Overflow

admin2025-04-29  3

I have this chain of actions to orchestrate:

  • A) check if user has already paid boolean checkUserPayment(Long userId)
  • B) if above A) is true, then proceed with UserInformation fetchUserInformationFromAPI(Long userID)
  • B) if above A) is false, then break immediatly and do return Mono.just(PaymentResponse.alreadyPaid(userId))
  • C) if UserInformation fetchUserInformationFromAPI(Long userID) yields a value then
  • D) initiate Payment via PaymentResponse sendPaymentRequest(PaymentRequest paymentRequest)
  • E) if C) does not yield an user or somehow breaks, don't go to D) instead return Mono.just(PaymentResponse.Error(throwable)

So all in all i want a method like:
Mono<PaymentResponse initiatePayment(Long userID) which orchestrates the above steps ...

Does Mono support such scenarios?

Thanks for your input!

EDIT: Based on the first answer, i want a single method, because all the subsequent steps are methods too. So in a non reactive way, it would look like this:

public PaymentResponse(Long userId){
    if(checkUserPayment(userId){
       return PaymentResponse.AlreadyPaid(userId);
    }
    UserInformation ui = fetchUserInformationFromAPI(Long userID);
    if(ui == null) return PaymentResponse.Error(userId)
    PaymentResponse pr = sendPaymentRequest(PaymentRequest paymentRequest);
    if(pr == null) return PaymentResponse.Error(userId);
    return pr;
}

I have this chain of actions to orchestrate:

  • A) check if user has already paid boolean checkUserPayment(Long userId)
  • B) if above A) is true, then proceed with UserInformation fetchUserInformationFromAPI(Long userID)
  • B) if above A) is false, then break immediatly and do return Mono.just(PaymentResponse.alreadyPaid(userId))
  • C) if UserInformation fetchUserInformationFromAPI(Long userID) yields a value then
  • D) initiate Payment via PaymentResponse sendPaymentRequest(PaymentRequest paymentRequest)
  • E) if C) does not yield an user or somehow breaks, don't go to D) instead return Mono.just(PaymentResponse.Error(throwable)

So all in all i want a method like:
Mono<PaymentResponse initiatePayment(Long userID) which orchestrates the above steps ...

Does Mono support such scenarios?

Thanks for your input!

EDIT: Based on the first answer, i want a single method, because all the subsequent steps are methods too. So in a non reactive way, it would look like this:

public PaymentResponse(Long userId){
    if(checkUserPayment(userId){
       return PaymentResponse.AlreadyPaid(userId);
    }
    UserInformation ui = fetchUserInformationFromAPI(Long userID);
    if(ui == null) return PaymentResponse.Error(userId)
    PaymentResponse pr = sendPaymentRequest(PaymentRequest paymentRequest);
    if(pr == null) return PaymentResponse.Error(userId);
    return pr;
}
Share Improve this question edited Jan 9 at 6:01 Thomas Lang asked Jan 8 at 12:49 Thomas LangThomas Lang 1,4953 gold badges22 silver badges39 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

Reactive supports such type of scenarios. A general advice would be to split the execution in smaller methods. have a look at above sample.

public Mono<PaymentResponse> initiatePayment(Long userID){
    return Mono.fromSupplier(()->userID)
        .map(id->checkUserPayment(id))
        .flatMap(pending->pending ? someOtherOperation(userID): Mono.just(PaymentResponse.alreadyPaid(userId)));
}

public Mono<PaymentResponse> someOtherOperation(Long userID){
    return Mono.fromSupplier(()->userID)
        .map(id->fetchUserInformationFromAPI(id))
        .map(userInfo->sendPaymentRequest(PaymentRequest.from(userInfo)))
        .onErrorResume(throwable->Mono.just(PaymentResponse.Error(throwable)));
}
转载请注明原文地址:http://anycun.com/QandA/1745857397a91300.html