avatarSaeed Zarinfam

Summary

The article compares three HTTP client libraries in Spring Boot: RestTemplate, WebClient, and the newly introduced RestClient, providing insights on their usage, features, and recommendations for when to use each.

Abstract

The article "RestClient vs. WebClient vs. RestTemplate" delves into the complexities of choosing the right HTTP client library for Spring Boot applications, especially with the introduction of the RestClient in Spring Boot 3.2. It outlines the evolution of these libraries, starting with the synchronous and blocking nature of RestTemplate, which was the go-to choice before the advent of WebFlux. The author explains the transition to WebClient, designed for non-blocking, reactive programming with Spring WebFlux. With the latest addition, RestClient, developers now have a modern, fluent API library for synchronous operations without the need for WebFlux dependencies. The article also discusses the declarative HTTP interface support across all three libraries, the pros and cons of RestTemplate, the benefits and costs of using WebClient in a blocking environment, and the rationale behind the creation of RestClient. The author provides code examples for each library, compares their features, and advises on migration strategies, suggesting RestClient as the preferred choice for new Spring MVC projects and for replacing RestTemplate in existing ones, while WebClient remains the standard for WebFlux projects. The article concludes with a demonstration of how to observe HTTP client calls using Digma, a local observability tool, and offers a GitHub repository with sample applications for hands-on comparison.

Opinions

  • The author posits that RestTemplate, while once the standard, is now considered old-fashioned and is being phased out in favor of more modern libraries.
  • WebClient is praised for its non-blocking, reactive capabilities and its functional and fluent API, but it is noted that its use in blocking environments (like Spring MVC) requires an understanding of reactive programming and may introduce unnecessary complexity.
  • RestClient is presented as a significant improvement over RestTemplate, offering a modern API without the need for WebFlux, making it an attractive choice for developers working on synchronous Spring MVC applications.
  • The author recommends using RestClient for new projects and considering it for migration from RestTemplate or WebClient in existing projects that do not require WebFlux's reactive stack.
  • The use of Digma for observing HTTP client calls is endorsed as a valuable tool for developers to gain insights into their applications' behavior during development.

RestClient vs. WebClient vs RestTemplate

Using the suitable library to call REST API in Spring ‌Boot

I recently wrote an article about how to use WebClient synchronously in the Spring Web MVC stack and described if it is a good idea to call the WebClient block() operation in this case:

But after releasing Spring Boot 3.2, the story of calling REST APIs from a Spring Boot application has become even more complicated. By releasing Spring Boot 3.2, another new library has entered the game in this area: the RestClient library.

In this article, I will compare these three libraries for calling REST APIs in Spring Boot applications. I will also give some recommendations of which one is the right choice for different situations.

What does RestTemplate lack from its competitors?

Before the emergence of the WebFlux stack, RestTemplate was the best choice to have a full-fledged synchronous HTTP client library for the Spring Framework since version 3.0. Before starting to know why we need to have another HTTP client library in Spring Framework, let’s get to know RestTemplate and its pros and cons.

In our example in this article, We have a hypothetical service called echo-service that provides echo REST API (using HTTP GET), and we want to call that API using these three libraries that Spring Boot provides us to see differences and similarities (you can find more description and the GitHub repository link at the last section).

Calling the echo service using RestTemplate

Using the RestTemplate in Spring Boot is very straightforward. We can create it from the RestTemplateBuilder either inside of our controller or service:

 private final RestTemplate restTemplate;

 public RestTemplateController(RestTemplateBuilder builder) {
     this.restTemplate = builder.build();
 }

Or in a separate configuration class:

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }
}

Now we can use the RestTemplate bean, in our example, we use it directly in a RestController (for the sake of simplicity, we keep the example simple, it is not a good idea to use any of these three libraries directly in the controller, it is better to define an EchoClient and use them there):

    @GetMapping("/echo/{message}")
    public Echo echo(@PathVariable String message) {
        return restTemplate.getForObject("http://localhost:8080/echo/" + message, Echo.class);
    }

RestTemplate provides several groups of overloaded methods based on the Spring template pattern:

  • XXXForObject (most straightforward)
  • XXXForEntity (represent more information)
  • exchange (more generalized with extra flexibility)
  • execute (most generalized with full control)

RestTemplate supports the declarative HTTP interface!

Incredibly, many Spring developers do not know that similar to WebClient and RestClient, the RestTemplate also supports defining an HTTP service as a Java interface using the @HttpExchange annotation. This cool feature in Spring Framework allows us to define an HTTP service as an interface. For example, the echo-service interface will be similar to this:

@HttpExchange(url = "/echo")
public interface EchoService {

    @GetExchange("/{message}")
    Echo echo(@PathVariable String message);

}

Now, we should create a proxy to perform requests through a RestTemplate instance and create a bean from the EchoService interface:

    @Bean
    public EchoService echoService() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory("http://localhost:8080"));
        RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

        return factory.createClient(EchoService.class);
    }

RestTemplate pros and cons

Like any library, RestTemplate has its pros and cons. Knowing about them will help us to make the best of it and also allow us to compare it with two other libraries in the following:

Pros:

  • Switchable underlying HTTP client library
  • Supports declarative HTTP interface
  • Highly configurable
  • Usable in older versions of Spring Framework

Cons:

  • Having multiple overloads of a method makes this library hard to use
  • The classic Spring template pattern is old-fashioned
  • Not suitable for non-blocking environments (for example, WebFlux)

What did WebClient bring us new?

As we discussed in the previous sections, RestTemplate is a simple and flexible library to call HTTP services, but it was synchronous and blocking, and it was the main reason that The Spring non-blocking stack (WebFlux) introduced a new and modern and fully non-block and Asynchronous HTTP client library with functional and fluent API called WebClient.

WebClient was introduced and designed specifically for the WebFlux stack. Unlike RestTemplate, it was not based on an old-fashioned template-based API and followed the modern functional and fluent style API.

The WebClient API is much clearer than the RestTemplate, and they are equivalent to HTTP methods.

Calling the echo service using WebClient

Very similar to RestTemplate, first, we need to create a bean using the WebClient.Builder class:

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient(WebClient.Builder builder) {
        return builder
                .baseUrl("http://localhost:8080")
                .build();
    }

}

Then inject the WebClient bean into the controller and use it:

    @GetMapping("/echo/{message}")
    public Mono<Echo> echo(@PathVariable String message) {
        return webClient
                .get()
                .uri("/echo/" + message)
                .retrieve()
                .bodyToMono(Echo.class);
    }

As I said before, WebClient was designed for WebFlux, and the API and threading model differs from the RestTemplate. WebClient was introduced in Spring Framework 5, although it was designed for Spring WebFlux but heavily used in the blocking stack (Web MVC) by developers by calling the block() operation from WebClient:

    @GetMapping("/echo/{message}")
    public Echo echo(@PathVariable String message) {
        return webClient
                .get()
                .uri("/echo/" + message)
                .retrieve()
                .bodyToMono(Echo.class)
                .block();
    }

In this article, I describe in detail that, technically, there is not any problem with using WebClient in the Web MVC stack and calling the block() operation:

When we call the block() method on the WebClient return type, it will block the calling thread from the WebMVC thread pool, and as a result, the WebClient can continue to call external services or APIs asynchronous and non-blocking.

In this way, you can have all the benefits of the WebClient API and its infrastructure (like non-blocking, performance and streaming support, and more), but the cost is to add extra library dependency to your Web MVC project (WebFlux and Project Reactor).

Defining declarative HTTP interface using WebClient

Like the RestTemplate, WebClient also supports defining an HTTP service as a Java interface using the @HttpExchange annotation. Implementing the interface and its methods are similar to the RestTemplate, the only difference is when we want to create a proxy to perform requests and attach it to the WebClient instance and create a bean from the EchoService interface:

    @Bean("wc")
    public EchoService echoService() {
        WebClient webClient = WebClient.builder().baseUrl("http://localhost:8080").build();
        WebClientAdapter adapter = WebClientAdapter.create(webClient);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

        return factory.createClient(EchoService.class);
    }

Yet another HTTP client library for Spring Framework. Why?

Why do we need another HTTP client in Spring Framework when we have RestTemplate and WebClient?

Now, by knowing the story behind the RestTemplate and WebClient, you can understand why we need another HTTP client library in Spring Framework.

RestClient was introduced in Spring Framework 6.1 and has the same infrastructure and abstraction as RestTemplate, which means it is blocking, but it has a fluent API similar to WebClient.

Calling the echo service using RestClient

Again, very similar to RestTemplate and WebClient, we can create a bean using the RestClient.builder() method:

    @Bean
    public RestClient restClient() {
        return RestClient.builder()
                .baseUrl("http://localhost:8080")
                .build();
    }

Then inject the RestClient bean into the controller and use it:

    @GetMapping("/echo/{message}")
    public Echo echo(@PathVariable String message) {
        return restClient
                .get()
                .uri("/echo/" + message)
                .retrieve()
                .body(Echo.class);
    }

As you can see in this example, the RestClient API is almost identical to the WebClient API, except we don't need to have the WebFlux library in our dependency and also call the block() method!

If you don't want to have the Spring WebFlux dependency in your Spring MVC project, RestClient is a good choice, and keep the codes in your project unmixed.

Migrate from RestTemplate to RestClient

The Spring Framework team recommends using RestClient for the new Spring MVC project and also provides guidelines to migrate from RestTemlate to RestClient.

Read this part of Spring Framework reference documentation to learn more about migrating from RestTemplate to RestClient.

Defining declarative HTTP interface using RestClient

RestClient can be used for declarative HTTP interfaces similar to RestTemplate and WebClient. It can be used with @GetExchange and @HttpExchange annotations to define our HTTP client in a declarative approach.

Implementing the interface and its methods are similar to the RestTemplate and WebClient, the only difference is when we want to create a proxy to perform requests and attach it to the RestClient instance and create a bean from the EchoService interface:

    @Bean("rc")
    public EchoService echoService() {
        RestClient restClient = RestClient.builder().baseUrl("http://localhost:8080/").build();
        RestClientAdapter adapter = RestClientAdapter.create(restClient);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

        return factory.createClient(EchoService.class);
    }

Final comparison and advice

RestClient, WebClient, and RestTemplate are all wrappers for a networking library that allows you to perform HTTP requests. The most important differences are in the programming paradigms and the API design approaches. In the following table, you can see the comparison between the three libraries:

As you can see in the table above, RestClient is a game changer. If you are looking for an HTTP client in a Spring MVC stack, we no longer need to use WebClient to have a modern and functional API. So, RestClient is the best choice for us if we are starting a greenfield project based on the Spring MVC stack. For existing projects based on the Spring MVC stack that have used RestTemplate, It can be a good option to replace it with RestClient because the RestTemplate is now in maintenance mode, and it will not be updated anymore. For blocking Spring projects that use WebClient, because of its functional and modern API, it is time to consider using RestClient because migrating from WebClient to RestClient for the Web MVC stack will not take long, and it will be worth the effort.

Of course, WebClient is still the best and the only official option for the Spring WebFlux projects.

Observe HTTP client calls using Digma

One of the advantages of using Digma is the ability to observe HTTP client calls between our services or even external services during the development time. Digma provides us with all activities, metrics, and traces inside the IDE when we test services on our local machine.

Sample application services

For this article, I will provide three services. The echo-service service provides a simple echo REST API for two other caller services. The first caller service is called reactive-caller, which uses WebFlux stack and WebClient to call echo REST API, and the second caller service is called blocking-caller, which uses Web MVC stack and all 3 HTTP client libraries (RestClient, WebClient, and RestTemplate) to call echo REST API.

The code for these services can be found in this GitHub repository.

Observe HTTP Client's Activities and Traces locally using Digma

After setting up the Digma plugin for IntelliJ IDEA, You can clone the repository and run the services locally. For example, you can call the echo REST API using the RestTemplate library in the blocking-caller service as follows (using HTTPie):

http :8081/rt/echo/hello

Now, in the Digma view, in the assets list, you can see that Digma detects one HTTP client:

If you click on the HTTP client section, you can see more details about this client call, like performance or to which service it belongs, and more:

To observe recent calls, traces, and also metrics, you need to open the Observability view:

To see the trace and metrics, click on the trace icon in the Actions column:

As you saw, Digma allows us to observe the HTTP client’s activities and traces locally inside the IntelliJ IDEA.

Final Thoughts

By introducing the RestClient, Spring developers now have a modern alternative to RestTemplate with functional and fluent API similar to WebClient but suitable for synchronous programming models in the Spring WebMVC stack. Although RestTemplate is being deprecated, it is still in maintenance mode and will receive updates as needed. However, it is highly recommended to use RestClient instead of RestTemplate for new projects or even migrate to RestClient for existing projects.

You can follow me for upcoming stories:

Read my short technical posts on Twitter.

Spring Boot
Restclient
Webclient
Resttemplate
Httpclient
Recommended from ReadMedium