Tag Archives: RestTemplate

Spring WebClient vs RestTemplate – Comparison and Features

Introduction

Spring 5 introduced a new reactive web client called WebClient. In this post, I will show when and how we can use Spring WebClient vs RestTemplate. I will also describe what features WebClient offers.

What is RestTemplate?

RestTemplate is a central Spring class that allows HTTP access from the client-side. RestTemplate offers POST, GET, PUT, DELETE, HEAD, and OPTIONS HTTP methods. The simple use case of RestTemplate is to consume Restful web services.

You can create a bean that provides the instance of RestTemplate. You can then @autowire this bean in any class where you plan to call REST services. RestTemplate is the class that implements the interface RestOperations.

The following code shows the declaration of the bean:

    @Bean
    public RestOperations restOperations()
    {
        return new RestTemplate();
    }

The following code shows a REST client `YelpClient` calling Yelp’s REST API to get rental property reviews.

   @Autowired
   private final RestOperations restOperations;

   public List getRentalPropertyReviews(String address)
   {
        String url = buildRestUrl(businessId);
        HttpHeaders httpHeaders = new HttpHeaders();
        String apiKey = getApiKey(YELP);
        httpHeaders.add("Authorization","Bearer " + apiKey);
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity entity = new HttpEntity("parameters", httpHeaders);
        ResponseEntity response;

        try
        {
            response = restOperations.exchange(url, HttpMethod.GET,entity, String.class);
        }
        catch(RestClientException e)
        {
            throw new RuntimeException("Unable to retrieve reviews", e);
        }

    }

In the above code, we are building HTTP Headers by adding Yelp’s REST API key as part of the authorization. We call the GET method to get review data.

Basically, one has to do

  • Autowire the RestTemplate object
  • Build HTTP Headers with authorization and Content Type
  • Use HttpEntity to wrap the request object
  • Provide URL, Http Method, and the Return type for exchange method.

What is WebClient?

Spring 5 introduced a reactive web client called WebClient. It’s an interface to perform web requests. It is part of the Spring web reactive module. WebClient will be replacing RestTemplate eventually.

Most importantly, WebClient is reactive, nonblocking, asynchronous, and works over HTTP protocol Http/1.1.

To use WebClient, one has to do

  • Create an instance of WebClient
  • Make a request to the REST endpoint
  • handle the response

 

   WebClient webClient = WebClient
       .builder()
       .baseUrl("https://localhost:8443")
       .defaultCookie("cookieKey", "cookieValue")
       .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 
       .defaultUriVariables(Collections.singletonMap("url", "https://localhost:8443"))
       .build();

The above code shows one way to instantiate WebClient. You can also create an instance by simply using WebClient webClient = WebClient.create();

WebClient provides two methods exchange and retrieve . exchange method usually fetches the response along with status and headers. retrieve method gets the response body directly. It’s easier to use.

Also depending on if you are trying to fetch a single object in response or a list of objects, you can use mono or flux.

this.webClient =
                webClientBuilder.baseUrl("http://localhost:8080/v1/betterjavacode/").build();

this.webClient.get()
                .uri("users")
                .accept(MediaType.APPLICATION_JSON)
                .retrieve().bodyToFlux(UserDto.class).collectList();

The above code basically uses webClient to fetch a list of users from the REST API.

Spring WebClient vs RestTemplate

We already know the one key difference between these two features. WebClient is a non-blocking client and RestTemplate is a blocking client.

RestTemplate uses Java Servlet API under the hood. Servlet API is a synchronous caller. Because it is synchronous, the thread will block until webclient responds to the request.

Consequently, Requests waiting for results will increase. This will result in an increase in memory.

On the other hand, WebClient is an asynchronous non-blocking client. It uses Spring’s reactive framework under the hood. WebClient is a part of the Spring-WebFlux module.

Spring WebFlux uses reactor library. It provides Mono and Flux API to work data sequences. Reactor is a reactive streams library. And, all of its operators support non-blocking back pressure.

Example of how to use WebClient in a Spring Boot Application

We can combine the capabilities of Spring Web MVC and Spring WebFlux. In this section, I will create a sample application. This application will call a REST API using WebFlux and we will build a response to show a web page with a list of users.

RestController for this example is an API to get a list of users:

package com.betterjavacode.webclientdemo.controllers;

import com.betterjavacode.webclientdemo.dto.UserDto;
import com.betterjavacode.webclientdemo.managers.UserManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("v1/betterjavacode")
public class UserController
{
    @Autowired
    public UserManager userManager;

    @GetMapping(value = "/users")
    public List getUsers()
    {
        return userManager.getAllUsers();
    }
}

Controller class that uses a WebClient to call REST API looks like below:

package com.betterjavacode.webclientdemo.controllers;

import com.betterjavacode.webclientdemo.clients.UserClient;
import com.betterjavacode.webclientdemo.dto.UserDto;
import com.betterjavacode.webclientdemo.managers.UserManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@Controller
public class MainController
{
    @Autowired
    UserClient userClient;

    @GetMapping(value = "/")
    public String home()
    {
        return "home";
    }

    @GetMapping(value = "/users")
    public String getUsers(Model model)
    {
        List users = userClient.getUsers().block();

        model.addAttribute("userslist", users);
        return "users";
    }
}

Now, the important piece of code of UserClient is where we will be using WebClient to call REST API.

package com.betterjavacode.webclientdemo.clients;

import com.betterjavacode.webclientdemo.dto.UserDto;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;

@Service
public class UserClient
{

    private WebClient webClient;

    public UserClient(WebClient.Builder webClientBuilder)
    {
        this.webClient =
                webClientBuilder.baseUrl("http://localhost:8080/v1/betterjavacode/").build();
    }

    public Mono<List> getUsers()
    {
        return this.webClient.get()
                .uri("users")
                .accept(MediaType.APPLICATION_JSON)
                .retrieve().bodyToFlux(UserDto.class).collectList();
    }
}

Above code shows first building the WebClient and then using it to retrieve response from REST API. retrieve method offers two options of mono or flux. Since we have more than one user to get, we are using flux.

This shows we can use reactive, non-blocking WebClient which is part of WebFlux in Spring Web MVC framework.

What Else Is There in Spring WebClient?

Spring WebClient is part of Spring WebFlux framework. The major advantage of this API is that the developer doesn’t have to worry about concurrency or threads. WebClient takes care of that.

WebClient has a built-in HTTP Client library support to perform requests with. That includes Apache HttpComponents, Jetty Reactive HttpClient, or Reactor Netty.

WebClient.builder() offers following options:

  • uriBuilderFactory – customized uriBuilderFactory to use base URL
  • defaultHeader – Headers for every request
  • defaultCookie – Cookies for every request
  • defaultRequest – To customize every request
  • filter – Client filter for every request
  • exchangeStrategies – HTTP Message reader/writer customizations

I already showed retrieve method in the above code demo.

WebClient also offers a method exchange with varients like exchangeToMono and exchangeToFlux.

With attribute(), we can also add attributes to the request.

Alternatively, one can use WebClient for synchronous use also. In my example above MainController, I use block to get the final result. This basically blocks parallel calls till we get the result.

One key feature that WebClient offers is retryWhen(). For more resilient system, it is a great feature that you can add while using WebClient.

        webClient
            .get()
            .uri(String.join("", "/users", id))
            .retrieve()
            .bodyToMono(UserDto.class)
            .retryWhen(Retry.fixedDelay(5, Duration.ofMillis(100)))
            .block();

retryWhen takes Retry class as a parameter.

WebClient also offers a feature for error handling. doOnError() allows you to handle the error. It is triggered when mono ends with an error. onErrorResume() is a fallback based on the error.

Conclusion

In this post, I showed what is Spring WebClient is, how we can use Spring WebClient vs RestTemplate, and what different features it offers.

If you enjoyed this post, you can subscribe to my blog here.

References

  1. Spring WebClient – Spring Documentation
  2. WebClient Cheatsheet – Spring WebClient

Consuming a RESTful Webservice – Part IV

Continuing the series of posts on Spring Boot, in this post, we will investigate how to consume a REST API service we built previously. This will be a short post on how to use Rest Template to call REST service. We will show how to read the data and how to post the data with some of the features Spring Boot offers to consume a REST service for the client-side.

The eventual goal is to use this feature to call our rest service during runtime to use the data from the database to display on views that a user will be able to see.

You can read previous posts on this series Part I, Part II, and Part III.

Purpose

The purpose of this post is to read company data from Company REST API and also to create a company by posting company data using the same REST API.

Build a client with Rest Template

To consume a rest service programmatically, Spring provides a feature called RestTemplate. RestTemplate is the easiest way for a client to interact with the server-side code with just one line of code.

In our client code, we will need a RestTemplate object, REST service URL. Since this is a sample we are building, we will be adding the main method in this class to run this client side of the code. In real-life scenarios, during runtime, client code will call the rest template to get server-side data, and use that data to massage or display to the user on the user interface.

 

RestTemplate restTemplate = new RestTemplate();
String resourceAPI_URL = "http://localhost:8080/benefits/v1/companies/{id}";
Company company = restTemplate.getForObject(resourceAPI_URL, Company.class, 1);

This code is showing that we are calling REST service to read company data for a company with id that a client will pass.

Similarly, we will have another request to post the data on the server side to create a company. The code for that will look like below:

String resourceAPI_POSTURL = "http://localhost:8080/benefits/v1/companies/";

Company comp = new Company();

comp.setName("XYZ Company");
comp.setStatusid(1);
comp.setType("Corporation");
comp.setEin("9343423232");

Company newcomp = restTemplate.postForObject(resourceAPI_POSTURL, comp, Company.class);

In this post, we showed how to use RestTemplate a feature that Spring Boot provides to consume a REST service. The code for this is available here

Home » RestTemplate