Last updated
Was this helpful?
Last updated
Was this helpful?
WebClient
is a non-blocking, reactive HTTP client introduced in Spring 5 and is part of the Spring WebFlux module. Reactor is the foundation of WebClient’s functional and fluent API for making HTTP requests in Spring applications, especially in reactive, non-blocking scenarios. It's designed for modern, scalable applications that can handle high volumes of concurrent requests efficiently.
Non-blocking and Reactive: WebClient
operates in a non-blocking manner, allowing application to handle multiple concurrent requests efficiently without blocking threads.
Fluent API: It offers a fluent and functional API for building and executing HTTP requests, making it easy to compose complex requests and handle responses.
Supports Reactive Streams: WebClient
integrates well with reactive programming concepts and supports reactive streams, allowing to work with Mono
and Flux
types for handling asynchronous data streams.
Customizable and Extensible: WebClient
provides various configuration options and allows customization of request and response handling through filters, interceptors, and other mechanisms.
Supports WebClient.Builder: We can create a WebClient
instance using WebClient.Builder
, which allows for centralized configuration and reuse across multiple requests.
Codec Integration: WebClient integrates with Spring's HTTP codecs for automatic marshalling and unmarshalling of request and response data formats (e.g., JSON, XML).
The default HttpClient used by WebClient is the Netty implementation, so to see details like requests we need to change the reactor.netty.http.client** logging level to _DEBUG**._
Base URL:
This specifies the default root URL for the requests.
Default Headers:
We can pre-set headers that will be included in every request made with this WebClient instance.
Timeouts:
Configure timeouts to prevent application from hanging indefinitely if a response takes too long. We can set timeouts for connection establishment, read operations, and write operations.
Interceptors:
Interceptors allows us to intercept requests and responses before and after their execution. We can use them for tasks like logging, adding authentication headers dynamically, or error handling.
Error Handling:
WebClient allows to chain error handling logic using operators like onErrorResume
or onErrorReturn
. This helps to gracefully handle unexpected errors and provide appropriate responses.
Retry:
WebClient provides the onErrorRetry
operator for retrying a failed request a certain number of times. This is useful for handling transient errors like network issues or server overload.
WebClient offers a fluent API for building different types of HTTP requests:
.retrieve()
: Use this for GET requests.
.post()
: Use this for POST requests.
.put()
: Use this for PUT requests.
.patch()
: Use this for PATCH requests.
.delete()
: Use this for DELETE requests
exchange()
: This method allows explicit handling of the request and response. It returns a ClientResponse object, which contains details such as status, headers, and the response body. With exchange(), we need to explicitly subscribe to the response using methods like subscribe(), block(), or similar ones. This gives more control over the execution of the request and when we want to consume the response. exchange() is deprecated in the latest versions.
When using WebClient
in Spring WebFlux, the bodyToMono()
and bodyToFlux()
methods expect to deserialize the response body into a specified class type. If the response status code indicates a client error (4xx) or a server error (5xx), and there's no response body, these methods will throw a WebClientException
Under the hood, WebClient
operates using an ExchangeFunction
, which is responsible for executing requests and handling responses. We can customize this behavior by providing our own ExchangeFunction
implementation.
We can use bodyToMono(Void.class)
if no response body is expected. This is helpful in DELETE operations.
Service 2
Dependency
SampleController.java
application.yaml
Build and run the application
Service 1
Dependency
SampleController.java
WebClientConfig.java
SampleService.java
application.yaml
Build and run the application
Execute the service 1 API via Postman
Monitor the logs (have a look at the threads executing the code)