Zip Three Different Mono of Different Type

Viewed 30110

I have started a new project using Spring Webflux and I am fairly new to this reactive coding paradigm. So apologies in advance for questioning like newbies.

My controller method returns the response as Mono<ResponseEntity<String>> and I have three different services to call from where I am getting three different Mono object like this -

Mono<CustomObject> customMono = serivce1.method();
Mono<Boolean> booleanMono = service2.method();
Mono<String> stringMono = service3.method();

So in order prepare the response(Mono<ResponseEntity<String>>), I need to do something like this -

Mono.zip(customMono, booleanMono, stringMono, (customData, booleanData, stringData) -> {
------
return Mono.just(ResponseEntity.ok().body("-----"));
});

The problem is, there are no such zip method to take 3 Mono and a function as parameters. I already found thise - https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#zip-reactor.core.publisher.Mono-reactor.core.publisher.Mono-java.util.function.BiFunction-

but it doesn't fulfil my requirement. So issues I am facing

  • I can not use Mono.mergeWith or Mono.concaWith method because my Mono object are of different kind.
  • I can flatMap/map every Mono and create a chain. But I want service2 to be called parallel in a separate thread as it is not dependent on service1 call. But service3 call is dependent on service1 response.

In summary, what I need to do:

  • make service1 call at first
  • make service2 call separately on different thread
  • make service3 call which is dependent on service1 call data
  • generating the final response object (Mono<ResponseEntity<String>>) using the data from all the service call.

Thanks in advance. As a newbie, any suggestion is appreciated.

2 Answers

Whenever you zip the two mono then the third parameter will be BiFunction but with three-parameter, it returns a flatmap of tuple then in the tuple you will get the response of other Monos. You need to modify your code in the below manner.

Mono.zip(customMono, booleanMono, stringMono).flatMap(data->{
 data.getT1();
 data.getT2();
 data.getT3();
 return <your_response_object>;
});

Now what will be the return type of getT1(),getT2() and getT3() ?

Obusally it will depend on what your Zip Mono return.

Hope so it will help you.

For your specific condition, you need Mono.zipWhen() which will ensure that your 3rd service call will have the data it requires from the response from service call 1

Mono.zip(monoResponse1,monoResponse2).zipWhen(data ->serviceCall3(data.getT1())).flatMap(response ->{
    response.getT1().getT1();//response from mono1
    response.getT1().getT2();//response from mono 2
    response.getT2();//response from mono 3
    return {create your mono response here};
} );
Related