Spring WebClient
is a non-blocking and reactive web client to perform HTTP requests. WebClient
has been added in Spring 5 (spring-webflux
module) and provides fluent functional style API.
Prior to Spring 5, RestTemplate has been the main technique for client-side HTTP accesses, which is part of the Spring MVC project.
Since Spring 5 release, WebClient
is the recommended approach.
1. WebClient
To use WebClient
api, we must have spring-boot-starter-webflux module imported into the project.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
1.1. Create and configure WebClient
To create WebClient
, we can follow any one of the given approaches.
1.1.1. WebClient.create() API
The create()
method is an overloaded method and can optionally accept a base URL for requests.
WebClient webClient1 = WebClient.create();
WebClient webClient2 = WebClient.create("https://client-domain.com");
1.1.2. WebClient.Builder API
WebClient webClient2 = WebClient.builder()
.baseUrl("http://localhost:3000")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
1.2. Sending Requests
To send a request, we can use its fluent API and execute the necessary steps as per requirements. For example, sending a HTTP POST request involves the following steps.
- Create
WebClient.UriSpec
reference usingmethod(HttpMethod)
or prebuilt methods such asget()
,put()
,post()
ordelete()
. - Set the request URI if not set already.
- Set the request headers and authentication details, if any.
- Set the request body, if any.
- Call the
retrieve()
orexchange()
method. Theretrieve()
method directly performs the HTTP request and retrieve the response body. Theexchange()
method returnsClientResponse
having the response status and headers. We can get the response body fromClientResponse
instance. - Handle the response returned from the server.
WebClient webClient = WebClient.create("http://localhost:3000");
Employee createdEmployee = webClient.post()
.uri("/employees")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(Mono.just(empl), Employee.class)
.retrieve()
.bodyToMono(Employee.class);
1.3. Handling Responses
If we are only interested in response body entity the using methods retrieve()
and then bodyToFlux()
and bodyToMono()
will serve the purpose.
Else, use the method exchange()
which will return the ClientResponse
which has all the response elements such as status, headers and response body as well.
Please note that bodyToMono()
and bodyToFlux()
methods always expect a response body of a given class type. If the response status code is 4xx (client error) or 5xx (Server error) i.e. there is no response body then these methods throw WebClientException
.
When using
exchange()
, we must always use any of thebody
ortoEntity
methods of ClientResponse to ensure resources are released and to avoid potential issues with HTTP connection pooling.Use
bodyToMono(Void.class)
if no response content is expected.
2. WebClient – GET API Example
Generally, we will use GET
API to fetch either collection of resources or a singular resource. Let’s see the example of both use cases using get()
method call.
HTTP GET /employees
: collection of employees asFlux
HTTP GET /employees/{id}
: single employee by id asMono
@Autowired
WebClient webClient;
public Flux<Employee> findAll()
{
return webClient.get()
.uri("/employees")
.retrieve()
.bodyToFlux(Employee.class);
}
public Mono<Employee> findById(Integer id)
{
return webClient.get()
.uri("/employees/" + id)
.retrieve()
/*.onStatus(httpStatus -> HttpStatus.NOT_FOUND.equals(httpStatus),
clientResponse -> Mono.empty())*/
.bodyToMono(Employee.class);
}
3. WebClient – POST API Example
POST
API is used commonly for creating a resource. Let’s see an example of post()
method to create an employee.
HTTP POST /employees
: creates a new employee from request body and returns the created employee in response.
@Autowired
WebClient webClient;
public Mono<Employee> create(Employee empl)
{
return webClient.post()
.uri("/employees")
.body(Mono.just(empl), Employee.class)
.retrieve()
.bodyToMono(Employee.class);
}
4. WebClient – PUT API Example
PUT
API is used commonly for updating a resource. Let’s see an example of put()
method to update an employee.
HTTP PUT /employees/{id}
: updates an existing employee data from request body and returns the updated employee in response.
@Autowired
WebClient webClient;
public Mono<Employee> update(Employee e)
{
return webClient.put()
.uri("/employees/" + e.getId())
.body(Mono.just(e), Employee.class)
.retrieve()
.bodyToMono(Employee.class);
}
5. WebClient – DELETE API Example
DELETE
API is used commonly for deleting a resource. Let’s see an example of delete()
method to delete an employee from records.
HTTP DELETE /employees/{id}
: deletes an existing employee by its id. It does not accept any request body as well as does not return any response body as well.
@Autowired
WebClient webClient;
public Mono<Void> delete(Integer id)
{
return webClient.delete()
.uri("/employees/" +id)
.retrieve()
.bodyToMono(Void.class);
}
6. Useful Configurations
6.1. Memory Limit
Spring WebFlux configures the default memory limit for buffering data in-memory to 256KB. If this limit is exceeded in any case then we will encounter DataBufferLimitException
error.
To reset the memory limit, configure the below property in application.properties
file.
spring.codec.max-in-memory-size=1MB
6.2. Connection Timeout
We can use HttpClient
class to set timeout periods for connection timeout, read timeout and write timeouts.
@Bean
public WebClient getWebClient()
{
HttpClient httpClient = HttpClient.create()
.tcpConfiguration(client ->
client.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler(10))
.addHandlerLast(new WriteTimeoutHandler(10))));
ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
return WebClient.builder()
.baseUrl("http://localhost:3000")
.clientConnector(connector)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
}
Drop me your questions related to Spring WebClient.
Happy Learning !!
Hi,
Your tutorial is very helpful. Could you please add how to call multiple apis in parallel with webclient.
Hi Lokesh,
Do you know how to solve this : Unable to connect to SSL services due to “PKIX Path Building Failed” error??
I’ve made a small program in java utilizing WebClient and i get this error
Hi, can you add a complete example using connection timeout for an Api request and a handled response? Thanks so much
I added this to my TODO list. I will post soon.
I am using the spring webclient 5.1.2.Release and .addHandlerLast( is giving the following error
class file for reactor.core.Disposable not found
1 error
Please help me to fix
Hi Lokesh
How do i use this webclient to get OAuth Token from a end point and then use that token to get a resource from another end point pls.