Open In App

Spring – WebClient vs RestTemplate

Last Updated : 21 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Reactor is the foundation of WebClient’s functional and fluid API (see Reactive Libraries), allowing declarative building of asynchronous logic without requiring knowledge of threads or concurrency. REST is an architectural set of limitations rather than a protocol or standard. It is also known as a web API or RESTful API. A client request simply sends an HTTP representation of the resource’s current state to the requester or the endpoint.

Spring WebClient

An HTTP request client is included in Spring WebFlux. Reactor is the foundation of WebClient’s functional and fluid API (see Reactive Libraries), allowing declarative building of asynchronous logic without requiring knowledge of threads or concurrency. It uses the same codecs that are also used to encode and decode request and response material on the server side, and it is completely non-blocking and streaming-compatible.

Implementation of Spring WebClient

Step 1: In your pom.xml file, add the Spring-boot-starter-web flux dependency

XML
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

Step 2: For usage in your project, create a bean that Spring WebClient may invoke

Java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class WebConfig {

  @Bean
  public WebClient webClient() {

    // Create a WebClient bean for making reactive web requests
    
    WebClient webClient = WebClient.builder()
      .baseUrl("http://localhost:3000") // Set the base URL for the requests
      .defaultCookie("cookie-name", "cookie-value") // Set a default cookie for the requests
      .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // Set a default header for the requests
      .build();
    
    return webClient; // Return the configured WebClient bean
  }
}

Step 3: Now use the methods provided by WebClient to perform HTTP requests

Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@Service
public class MyService {

  private final WebClient webClient;

  // Constructor-based dependency injection for WebClient
  @Autowired
  public MyService(WebClient webClient) {
    this.webClient = webClient;
  }

  // Method to create an employee using a POST request
  public Mono<Employee> createEmployee(Employee employee) {
    Mono<Employee> employeeMono = webClient.post()
      .uri("/employees")
      .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
      .body(Mono.just(employee), Employee.class)
      .retrieve()
      .bodyToMono(Employee.class);

    return employeeMono;
  }

  // Method to retrieve an employee using a GET request
  public Mono<Employee> getEmployee() {
    Mono<Employee> employeeMono = webClient.get()
      .uri("/employees/{id}", 123) // Assuming you want to retrieve an employee with ID 123
      .retrieve()
      .bodyToMono(Employee.class);

    return employeeMono;
  }
}

RestTemplate

REST APIs are becoming more and more common because of their heavy traffic and fast service accessibility. REST is an architectural set of limitations rather than a protocol or standard. It is also known as a web API or RESTful API. A client request simply sends an HTTP representation of the resource’s current state to the requester or to the endpoint.

Implementation of RestTemplate

Step 1: In your pom.xml file, add the Spring-Web dependency

XML
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

Step 2: To utilise and invoke the Spring RestTemplate in your project, create a bean

Java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.web.client.RestTemplate;

import java.time.Duration;

@Configuration
public class RestTemplateConfig {

  // Configuring a RestTemplate bean with timeout settings
  @Bean
  public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder
      .setConnectTimeout(Duration.ofMillis(3000)) // Set connection timeout to 3000 milliseconds
      .setReadTimeout(Duration.ofMillis(3000))    // Set read timeout to 3000 milliseconds
      .build();
  }
}

Step 3: You may now make HTTP requests using the RestTemplate methods

Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class ProductsRestClient {

  @Autowired
  private RestTemplate restTemplate;

  private static final String productsUrl = "https://api.product.com/name/watch";

  // Method to perform a GET request using getForEntity and retrieve the response body
  public Products getForEntity() {
    ResponseEntity<Products> response = restTemplate.getForEntity(productsUrl, Products.class);
    return response.getBody();
  }

  // Method to perform a GET request using getForObject and retrieve the response body
  public Products getForObject() {
    return restTemplate.getForObject(productsUrl, Products.class);
  }

  // Method to retrieve headers using headForHeaders and format them into a map
  public Map<String, String> getHeaders() {
    HttpHeaders httpHeaders = restTemplate.headForHeaders(productsUrl);

    Map<String, String> headerContent = new HashMap<>();
    httpHeaders.forEach((key, value) -> {
      headerContent.put(String.format("Header '%s'", key),
        String.join("|", value)); // Join header values with "|" separator
    });

    return headerContent;
  }
}

Call a Slow Service

Using Spring RestTemplate

Java
@GetMapping("/tweets-blocking")
public List<Tweet> getTweetsBlocking() {
    log.info("Starting BLOCKING Controller!");
    final String uri = getSlowServiceUri();

    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<List<Tweet>> response = restTemplate.exchange(
      uri, HttpMethod.GET, null,
      new ParameterizedTypeReference<List<Tweet>>(){});

    List<Tweet> result = response.getBody();
    result.forEach(tweet -> log.info(tweet.toString()));
    log.info("Exiting BLOCKING Controller!");
    return result;
}

Using Spring WebClient

Java
@GetMapping(value = "/tweets-non-blocking", 
            produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Tweet> getTweetsNonBlocking() {
    log.info("Starting NON-BLOCKING Controller!");
    Flux<Tweet> tweetFlux = WebClient.create()
      .get()
      .uri(getSlowServiceUri())
      .retrieve()
      .bodyToFlux(Tweet.class);

    tweetFlux.subscribe(tweet -> log.info(tweet.toString()));
    log.info("Exiting NON-BLOCKING Controller!");
    return tweetFlux;
}

Difference Between Spring WebClient and RestTemplate

Spring WebClient

Spring RestTemplate

In Spring WebClient,An HTTP request client is included in Spring WebFlux.

In Spring RestTemplate,REST APIs are becoming more and more common because of their heavy traffic and fast service accessibility.

Spring WebClient supports reactive spring and is based on event driven concepts.

Spring RestTemplate is synchronous and it’s reactive situations cannot use it.

Spring WebClient is asynchronous, it won’t stop the running thread while it waits for a response.

Spring RestTemplate is synchronous and blocking since it makes use of the Java Servlet API.

Spring WebClient requires Java 8 or higher.

Spring RestTemplate works with Java 6 and later versions.

Spring WebClient is a versatile library for facilitating communication.

Spring RestTemplate is an advanced abstraction.

Microservices, reactive apps, and situations needing a high level of concurrency are the greatest uses for WebClient.

Perfect for straightforward use cases and conventional monolithic apps in RestTemplate

Spring WebClient probably going to continue growing and getting assistance in springtime.

Spring RestTemplate receives security updates but does not receive any new features in future.

Conclusion

So this is Spring WebClient vs RestTemplate.An HTTP request client is included in Spring WebFlux. REST APIs are becoming more and more common because of their heavy traffic and fast service accessibility.Microservices, reactive apps, and situations needing a high level of concurrency are the greatest uses for it.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads