Reputation: 320
I have a use case where I need to make HTTP calls from my service.I do not want my threads to blocked waiting for the response to come back . How can I do this in SpringWebClient ? This is how my code looks
public void asyncHttp(HTTPMethod method,
String url,
String body,
Map<String, String> headers){
WebClient.UriSpec<WebClient.RequestBodySpec> uriSpec = webClient.method(method.getMethod());
WebClient.RequestBodySpec bodySpec = uriSpec.uri(url);
WebClient.RequestHeadersSpec<?> headersSpec = bodySpec.bodyValue(body);
for(Map.Entry<String, String> entry : headers.entrySet()){
headersSpec.header(entry.getKey(), entry.getValue());
}
Mono<JsonObject> responseMono = headersSpec.retrieve().bodyToMono(JsonObject.class);
}
I have two questions here
Upvotes: 1
Views: 13089
Reputation: 1675
Since your application is not completely reactive and you're using WebClient just to make HTTP calls, you can use Mono#toFuture(), Mono#SubscribeOn(), and Mono#timeout() for your use case
private CompletableFuture<Object> asyncHttpCall(HttpMethod httpMethod, String url, String body, Map<String, String> headers) {
return WebClient.create(url).method(httpMethod).bodyValue(body).headers(httpHeaders -> headers.forEach(httpHeaders::add))
.retrieve()
.bodyToMono(Object.class)
// specify timeout
.timeout(Duration.ofSeconds(5L))
// subscribe on a different thread from the given scheduler to avoid blocking as toFuture is a subscriber
.subscribeOn(Schedulers.single())
// subscribes to the mono and converts it to a completable future
.toFuture();
}
// execute asyncHttpCall
asyncHttpCall(HttpMethod.POST, "https://httpbin.org/post", "", Collections.emptyMap())
// consume the response from the CompletableFuture
.thenAccept(response -> System.out.println("response = " + response));
You can
asyncHttpCall
returns.asyncHttpCall
.Mono
inside asyncHttpCall
.Upvotes: 3