HelloKoding

Practical coding guides

Spring Boot WebClient Tutorial with Examples

Spring WebClient is a non-blocking, reactive client to perform HTTP requests, a part of Spring WebFlux framework

In this tutorial, you will learn how to use WebClient and take a look at the difference between its exchange() and retrieve() methods

What you’ll need

  • Your favorite IDE
  • JDK 8+ or OpenJDK 8+
  • Maven 3+

Add WebClient into your project

As WebClient is a part of Spring WebFlux, you can add it to the pom.xml or build.gradle file of your project via the spring-webflux dependency

In the Spring Boot project, you can add spring-boot-starter-webflux instead. The library versions can be omitted as it is resolved by the parent pom provided by Spring Boot

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

Create a WebClient instance

You can use either create(), create(baseUrl) or builder() factory methods of WebClient interface to create an instance

  • The create(baseUrl) method is more practical than create() method as it is handy and you can provide the default base URL for subsequence requests later
WebClient webClient1 = WebClient.create();
WebClient webClient2 = WebClient.create("http://localhost:8080");
  • Use builder() if you’d like to set the default headers and cookies
WebClient webClient = WebClient.builder()
    .baseUrl("http://localhost:8080")
    .defaultHeader(HttpHeaders.USER_AGENT, "Hello Koding")
    .defaultCookie("cookie name", "cookie value")
    .build();

Build an HTTP request with WebClient

You can build an HTTP request with WebClient by following these steps

  • Start with either get(), post(), put(), patch(), delete(), options() or head() in coressponding with HTTP GET, POST, PUT, PATCH, DELETE, OPTIONS and HEAD request respectively
  • Build request URI with uri(String) or uri(uriBuilder) if you’d like to send path variables or query parameters
  • Add custom cookies and request headers with cookies() and headers()
  • Perform the request and get the response with retrieve() or exchange()
  • Convert the response to Mono or Flux with bodyToMono() or bodyToFlux()

The following gives you an example on building a GET request

@Test
public void buildAnHttpRequest() {
    WebClient webClient = WebClient.create("http://localhost:8080");

    Mono<String> result = webClient.get()
        .uri(uriBuilder -> uriBuilder
            .path("/hello")
            .queryParam("name", "Koding")
            .build())
        .retrieve()
        .bodyToMono(String.class);

    assertThat(result.block())
        .isEqualTo("Hello, Koding!");
}

Exchange vs Retrieve in WebClient

The retrieve() method is a shortcut to using exchange(). Uses exchange() if you’d like to check and handle response error

The following gives you another version of the above example by using exchange()

@Test
public void exchange() {
    WebClient webClient = WebClient.create("http://localhost:8080");

    Mono<ClientResponse> result = webClient.get()
        .uri(uriBuilder -> uriBuilder
            .path("/hello")
            .queryParam("name", "Koding")
            .build())
        .exchange();

    assertThat(result.flatMap(res -> res.bodyToMono(String.class)).block())
        .isEqualTo("Hello, Koding!");
}

Conclusion

In this tutorial, we learned how to create a WebClient instance, and use it to build and execute an HTTP request. You can find the full source code as below

WebClientTest.java

package com.hellokoding.spring;

import org.junit.jupiter.api.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import static org.assertj.core.api.Assertions.assertThat;

public class WebClientTest {
    @Test
    public void createWebClient() {
        WebClient webClient1 = WebClient.create();
        WebClient webClient2 = WebClient.create("http://localhost:8080");
    }

    @Test
    public void createWebClientWithBuilder() {
        WebClient webClient = WebClient.builder()
            .baseUrl("http://localhost:8080")
            .defaultHeader(HttpHeaders.USER_AGENT, "Hello Koding")
            .defaultCookie("cookie name", "cookie value")
            .build();
    }

    @Test
    public void buildAnHttpRequest() {
        WebClient webClient = WebClient.create("http://localhost:8080");

        Mono<String> result = webClient.get()
            .uri(uriBuilder -> uriBuilder
                .path("/hello")
                .queryParam("name", "Koding")
                .build())
            .retrieve()
            .bodyToMono(String.class);

        assertThat(result.block())
            .isEqualTo("Hello, Koding!");
    }

    @Test
    public void exchange() {
        WebClient webClient = WebClient.create("http://localhost:8080");

        Mono<ClientResponse> result = webClient.get()
            .uri(uriBuilder -> uriBuilder
                .path("/hello")
                .queryParam("name", "Koding")
                .build())
            .exchange();

        assertThat(result.flatMap(res -> res.bodyToMono(String.class)).block())
            .isEqualTo("Hello, Koding!");
    }
}
Follow HelloKoding