springspring-mvcspring-webclientspring-asyncspring-resttemplate

Call Rest API by Spring RestTemplate within a @Async method


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;
    }