Spring WebClient vs. RestTemplate: What’s Difference?

Since Spring 5, the WebClient has been part of Spring WebFlux and is the preferred way to make HTTP requests. It is a preferred alternative to the classic RestTemplate which has been in maintenance mode since Spring 5.0.

This tutorial discusses the main differences between the Spring WebClient and RestTemplate classes.

1. A Quick Comparison between WebClient and RestTemplate

Before going deep into details, let us start with a quick comparison.

FeatureWebClientRestTemplate
Reactive ProgrammingBuilt on reactive principles and supports reactive programming.Synchronous and not designed for reactive programming.
TechnologyBuilt on Reactive stack.Built on Servlet stack.
Thread ModelUses non-blocking I/O and is suitable for handling a large number of concurrent requests.Uses blocking I/O that can lead to thread blocking in high-concurrency scenarios.
Java VersionRequires Java 8+ or higher. Supports functional programming.Compatible with Java 6+ or higher.
Error HandlingProvides robust error handling using operators like onErrorResume, onErrorReturn, etc.Error handling is typically done using try-catch blocks.
StreamingSupports streaming data using Flux and Mono, suitable for reactive streaming scenarios.Limited support for streaming and not well-suited for reactive streams.
Use CasesBest suited for microservices, reactive applications, and scenarios requiring high concurrency.Suitable for traditional monolithic applications and simple use cases.
DependenciesRequires the Spring WebFlux dependency.Requires the Spring Web dependency.
Future SupportAligned with the reactive programming model and likely to see continued development and support.May see maintenance updates but may not receive as much focus in the future.

2. Blocking RestTemplate vs. Non-blocking WebClient

This is the main deciding factor when choosing WebClient over RestTemplate in any application. Let us understand in more detail.

2.1. RestTemplate is Blocking

RestTemplate are blocking in nature and uses one thread-per-request model of Java Servlet API. It means that RestTemplate will wait for the response once it dispatches a request to the remote server. By default, RestTemplate creates new Httpconnection every time and closes the connection once the response is received and processed.

Creating and closing the URL connections is a costly operation. To efficiently use RestTemplate in our production class applications, we must use the HTTP connection pooling else performance will degrade fast. When there are a high number of requests in the application, there will be a high number of threads and connections, in proportion. This puts a load on the server resources. If the server is slow, users will soon start seeing degraded performance and even unresponsiveness in the application.

Please note that RestTemplate is thread-safe and a single instance can be shared across multiple connections at any time.

@Service
public class MyService {

  private final RestTemplate restTemplate;

  @Autowired
  public MyService(RestTemplate restTemplate) {
    this.restTemplate = restTemplate;
  }

  public String getData() {

    ResponseEntity<String> responseEntity 
      = restTemplate.getForEntity("https://api.example.com/data", String.class);
    String responseBody = responseEntity.getBody();
    return responseBody;
  }
}

2.2. WebClient is Non-blocking

Opposite to RestTemplate, the WebClient is asynchronous and non-blocking in nature. It follows event-driven architecture from the reactive framework of Spring WebFlux. Using WebClient, the client need not wait till the response comes back. Instead, it will be notified using a callback method when there is a response from the server.

When we invoke an API through WebClient that returns a Mono or a Flux, it will return immediately. The results of the call will be delivered to us through the mono or flux callbacks when they become available.

Please note that, if necessary, we can achieve RestTemplate like synchronous processing with WebClient.block() method.

@Service
public class MyService {

  private final WebClient webClient;

  @Autowired
  public MyService(WebClient webClient) {
    this.webClient = webClient;
  }

  public Mono<String> getData() {

    return webClient.get()
      .uri("/data")
      .retrieve()
      .bodyToMono(String.class)
      .subscribe(
          // onSuccess callback
          result -> {
            System.out.println("Success: " + result);
          },
          // onError callback
          error -> {
            System.err.println("Error: " + error.getMessage());
          }
      );
  }
}

3. Conclusion

From the above discussion, it is clear that the only big difference between WebClient and RestTemplate is their blocking nature. RestTemplate blocks the request threads while WebClient does not. We can use WebClient to make synchronous requests, but the opposite is not true. RestTemplate cannot make asynchronous requests.

While WebClient is the preferred way for future uses, RestTemplate seems to stay here for long though without any major feature addition.

While considering WebClient for our next application, we must remember that to build a truly non-blocking application, we must aim to create/use all of its components as non-blocking i.e. client, controller, middle services, and even the database. If one of them is blocking the requests, our purpose will be defeated.

Happy Learning !!

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.