Small question regarding Spring Webflux, and how to "chain" http calls please.
With a concrete example, here is a very straightforward sample with Spring MVC, with a rest template.
RestTemplate restTemplate = new RestTemplate();
HttpEntity<StepOneRequest> stepOneRequestHttpEntity = new HttpEntity<>(new StepOneRequest("foo", "bar"));
StepOneResponse stepOneResponse = restTemplate.postForObject("https://step-one-web-service:443/getStepTwoFromFooBar", stepOneRequestHttpEntity, StepOneResponse.class);
HttpEntity<StepTwoRequest> stepTwoRequestHttpEntity = new HttpEntity<>(new StepTwoRequest(stepOneResponse.getTheDependencyFromStepOne()));
StepTwoResponse stepTwoResponse = restTemplate.postForObject("https://step-two-web-service:443/getResponseFromStepTwo", stepTwoRequestHttpEntity, StepTwoResponse);
return ResponseEntity.ok(new MyResponse(stepTwoResponse.getImportantValueFromStepTwo()));
}
In this snippet, we see very straightforward. Initialisation of only one rest template.
Construction of a http request payload object.
Use the constructed object to query a first external web application API to get a response.
Important, the response of the first HTTP call is needed to make the second HTTP call. They can only be sequential, it needs the result of the first call, to be able to query the second API.
Then, the http call to the second API.
Finally, response based on the second API to the original requester.
Now, if this is translated to Webflux:
WebClient webClientStepOne = WebClient.create("https://step-one-web-service:443/getStepTwoFromFooBar");
WebClient webClientStepTwo = WebClient.create("https://step-two-web-service:443/getResponseFromStepTwo");
Mono<StepOneResponse> stepOneResponseMono = webClientStepOne.post().body(BodyInserters.fromValue(new StepOneRequest("foo", "bar"))).retrieve().bodyToMono(StepOneResponse.class);
Mono<StepTwoResponse> stepTwoResponseMono = stepOneResponseMono.flatMap(aStepOneResponse -> webClientStepTwo.post().body(BodyInserters.fromValue(aStepOneResponse.getTheDependencyFromStepOne())).retrieve().bodyToMono(StepTwoResponse.class));
return stepTwoResponseMono.map(aStepTwoResponse -> ResponseEntity.ok(new MyResponse(aStepTwoResponse.getImportantValueFromStepTwo())));
}
I have one big question here. While this is correct (it yields the same response) is this the correct thing to do?
Especially, the line with the flatMap
Mono<StepTwoResponse> stepTwoResponseMono = stepOneResponseMono.flatMap(aStepOneResponse -> webClientStepTwo.post().body(BodyInserters.fromValue(aStepOneResponse.getTheDependencyFromStepOne())).retrieve().bodyToMono(StepTwoResponse.class));
It seems very out of the picture. Is there a better way here?
Also, a side question, do we really need N WebClient if I need to chain N api calls please? The URLs are different, not just the path, the complete URL. When rest template can do with only one instance, it seems here, I need N WebClient if I need to call N external services.
What is the correct way to use WebClient here please? What is the correct way to chain http calls please?
Thank you