2

In my project we are using spring boot webflux, and I have this scenario where i have to call multiple api's from within a particular microservice synchronously. e.g.

for(String api:apiNames){
   //call api's
   }

As per my understanding, webClient works asynchronously, until and unless someone subscribe to it it wont release the response.

in my current scenario i have to make use of webclient and I have to call each api only after successfull execution of previous api.

Note:- api response can be anything success/failure

Please help me in implementing this synchronous call

2 Answers2

2

You can use the #block() method to make it synchronous. Example on a mono (https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#block--)

For example on the (asynchronous) webflux webclient:

return webClient.get()
                .uri(uri)
                .accept(MediaType.APPLICATION_JSON)
                .retrieve()
                .bodyToMono(String.class)
                .block();

The above example will wait with executing any next line of code untill it has received a response. After which you can just make another call to another api in the same way.

Edit: As pointed out in the comments I would like to add a warning that using #block() is not efficient and you should try and chain more reactive calls and try to avoid making your application non reactive.

A nice post with more details can be found here: https://stackoverflow.com/a/57365926/1326867

Nick Hol
  • 302
  • 1
  • 10
  • 1
    Blocking multiple times is very inneffective, spring recommends and i agree that you chain as many requests as possible withing the async world and to only call block once in the end, which is a lot better for performance. – Toerktumlare Feb 17 '22 at 18:24
  • He clearly states he needs to do all the calls in a synchronous fashion. Else I wouldve suggested mono.zip or flux.merge. If I am missing something in my answer maybe you could answser yourself? – Nick Hol Feb 17 '22 at 19:22
  • Please read up on what the `map` function on a flux does – Toerktumlare Feb 17 '22 at 19:39
  • anything else you want me to read? like flatMap? Not sure what you want to imply but what do you want me to answer with the given piece of code "String api:apiNames" Map/Flatmap what unknown results. I feel like I have answered his question. Answering all 'what if' scenario's and further 'optimalisation' based on assumption of his code seems out of scope and a bit off to downvote on. But thats my opinion. I do agree that I could've added a warning saying its not the proper way to use spring webclient. – Nick Hol Feb 17 '22 at 19:43
1

Although, the question uses the word "synchronously", the description rather seems to suggest that sequentiality is what is needed, meaning executing each request one after the other.

If that's the requirement, it can be implemented the following way with Reactor:

Flux.fromIterable(apiNames)
  .concatMap(apiName -> webClient...) // concatMap ensures sequential execution

However, if the application is a blocking Spring application, then Nick Hol's answer is also a correct one.

Martin Tarjányi
  • 8,863
  • 2
  • 31
  • 49
  • sry to replay late ,, but this is what i was looking for, many thanks , and also @Nick Hol, Thanks for your response , I rally appreciate it – Snehasis Rout Mar 09 '22 at 07:35