In this article, we are going to see the WebClient filters in Spring, based on the reactive framework introduced by Spring WebFlux.
To refresh knowledge about WebClient, you can take a look by clicking here.
Why use filters in WebClient with Spring?
Filters are commonly used with WebClient in Spring for several reasons:
- Logging and Tracing: Filters allow you to log the details of requests and responses exchanged between the client and the server. This can help with debugging, troubleshooting, and monitoring the communication flow. You can log request and response bodies, headers, and other relevant information.
- Authentication and Authorization: Filters provide a way to add authentication tokens, headers, or other credentials to the outgoing requests. They can handle authentication challenges and verify the received responses for authorization purposes. This is especially useful when interacting with secure APIs or services.
- Error Handling and Retries: Filters can handle errors and exceptions that occur during the request processing. They can automatically retry failed requests, handle timeouts, or perform custom error handling logic. This helps in building resilient and fault-tolerant communication with external services.
- Request and Response Transformation: Filters allow you to modify the request body, headers, or URL before sending it to the server. They can also transform the response body, headers, or status before returning it to the caller. This enables you to customize the data exchanged with the server, such as adding custom headers, modifying payloads, or transforming response formats.
- Caching: Filters can implement caching mechanisms to store and retrieve responses from a local cache. This can improve performance by reducing the number of requests sent to the server, especially for repeated requests with the same parameters.
- Monitoring and Metrics: Filters can collect metrics and statistics about the requests and responses, such as response times, throughput, or error rates. We can use this information for monitoring the performance and health of the system, as well as for generating reports and analytics.
- Request Interception and Manipulation: Filters intercept and analyze incoming requests before the server processes them. This allows you to perform tasks such as request validation, parameter manipulation, or adding additional metadata to the requests.
Overall, filters provide a way to customize and enhance the behavior of WebClient in Spring. They help in implementing cross-cutting concerns, improving security, adding resilience, and integrating with various third-party systems and protocols.
Client Request Filter
Generally, a filter is used to intercept and analyze a client request. For example, an HTTP request can be intercepted to view headers, parameters, or it can be intercepted to add authorization, logging, or anything you need in a request.
In Spring, we can intercept a request, for example, with HandlerInterceptor. However, with reactive programming, we are going to use the ExchangeFilterFunction interface.
Let’s see a simple example of using ExchangeFilterFunction:
private ExchangeFilterFunction logFilter() { return (clientRequest, next) -> { log.info("External Request to {}", clientRequest.url()); clientRequest.headers().forEach((name, values) -> { log.info("header: " + name + " with value " + values); }); return next.exchange(clientRequest); }; }
In this example, on one hand, we log the entire request, and on the other hand, we log the headers. Normally, a filter is returned by calling the next in the filter chain.
How to use a filter in WebClient?
One of the fields of the WebClient builder is filter, so once the WebClient is created, we add the filter.
return WebClient.builder() .baseUrl(url) .filters(exchangeFilterFunctions -> { exchangeFilterFunctions.add(logFilter()); exchangeFilterFunctions.add(authHeader()); }).defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .build();
In the previous example, we can see that we have added two different filters, one is the method we defined in the previous point, and the other is adding an authorization header.
Create an Authorization Filter
Often, it is necessary to propagate an authorization token when calling another microservice. In the following example, we use the ClientRequest.from() class to get the URL and add a header.
private ExchangeFilterFunction authHeader() { return (request, next) -> next.exchange(ClientRequest.from(request).headers((headers) -> { headers.set("Authorization", "Bearer " + infoUser.getAuthorizationBearer()); }).build()); }
As we can see in the previous example, we obtain the request and add the header to it.
Create a Basic Authentication Filter
Now let’s create a basic authentication filter that we can directly include. So, let’s add a basic authentication filter to the WebClient.
To add the next filter, we will use the basicAuthentication method provided by the ExchangeFilterFunction class.
private ExchangeFilterFunction basicAuthentication(String user, String password) { WebClient webClient = WebClient.builder() .filter(ExchangeFilterFunctions.basicAuthentication(user, password)) .build(); }
Conclusion
Briefly, we have seen how to add filters with Spring’s WebClient, which allows us to intercept and handle any request made.
If you need more information, you can leave us a comment or send an email to refactorizando.web@gmail.com You can also contact us through our social media channels on Facebook or twitter and we will be happy to assist you!!