Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring webflux difference between block, flatmap and subscribe

I have an api which needs to call 3 other apis, the second and third api calls rely on the result of the first.

I'm slightly confused about the best way to do this and the difference between using block, subscribe and flatmap. All 3 of these methods work for me but I am not sure which one is the best one to use.

This is what I currently have:

webClient1.getApi1(request.getId())
   .subscribe(api1Response -> {
      if (api1Response.hasData()) {
         Mono<ApiTwoResponse> monoTwo = webClient2
            .post()
            .syncBody(...)
            .bodyToMono(ApiTwoResponse.class)
         monoTwo.subscribe(two -> log.info(two));

         Mono<ApiThreeResponse> monoThree = webClient3
            .put()
            .syncBody(...)
            .bodyToMono(ApiThreeResponse.class)
         monoThree.subscribe(three -> log.info(three));
      } 
});

I've also tried block although this seems to be discouraged:

Api1Response response = webClient1.getApi1(request.getId()).block()

and i also tried flatmap although this forces you to return something:

webClient1.getApi1(request.getId())
   .flatmap(api1Response -> {
      ...
      return Mono.empty();
});

Any help and feedback on the above code is appreciated.

like image 437
mobbs Avatar asked Jul 01 '26 19:07

mobbs


1 Answers

block operation, stops and waits essentially. It would be the equivalent to Future.get() in java. It defeats the purpose of non-blocking code. Flatmap flattens a sequence of sequence into a single sequence, so a List {List{?}} will turn into a list{Object}. subscribe essentially starts to listen, and can perform actions. Usually nothing happens until subscribe.

But for your use case, you can use filter here is an example, Which looks filters over the {true, false} items, then for each filter that is true, I zip the results of two mono's together, then subscribe with an action

Flux<Boolean> bool = Flux.just(true, false);
    Mono<Integer> mono1 = Mono.just(1);
    Mono<String> mono2 = Mono.just("string");

    bool.filter(b -> b)
            .flatMap(b -> Mono.zip(mono1, mono2))
            .subscribe(tuple -> System.out.println(tuple.getT1() + ", " + tuple.getT2()));
like image 64
Kevin Hussey Avatar answered Jul 05 '26 06:07

Kevin Hussey