Issue
As I know, Spring RestTemplate is synchronous and blocks the thread until the web client receives the response, and Spring WebClient is asynchronous and non-blocking.
But what if we call an API using RestTemplate within an @Async annotated method?
Does it block the new thread created by @Async?
Finally, what's your suggestion for the async call of Rest APIs (without WebClient because I'm using Spring version older than 5). Thanks
Solution
what if we call an API using RestTemplate within an
@Async
annotated method?
The method will run asynchronously on the executor you specify in the @Async
annotation parameter. e.g. @Async("threadPool")
where "threadPool" is the name of the Executor bean.
Does it block the new thread created by @Async?
Yes, it will block the thread on which Spring runs your method. However, the thread won't necessarily be created by Spring, it can be taken from the thread pool you define in the @Async
annotation.
What's your suggestion for the async call of Rest APIs (without WebClient because I'm using Spring version older than 5)?
You can use CompletableFuture API or @Async
if you just need the "async" effect. But if you also need the "non-blocking" property you need to use some non-blocking HTTP client, for instance, okhttp.
The non-blocking async HTTP call with okhttp will look as follows:
public CompletableFuture<Response> call() {
Request request = new Request.Builder()
.url(URL)
.build();
Call call = client.newCall(request);
CompletableFuture<Response> result = new CompletableFuture<>();
call.enqueue(new Callback() {
public void onResponse(Call call, Response response) throws IOException {
result.complete(response);
}
public void onFailure(Call call, IOException e) {
result.completeExceptionally(e);
}
});
return result;
}
Answered By - Ilya Zinkovich