Zip Three Different Mono of Different Type

bivrantoshakil picture bivrantoshakil · Oct 18, 2019 · Viewed 12k times · Source

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.

Answer

Rahul harinkhede picture Rahul harinkhede · Oct 18, 2019

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.