This context provides a comprehensive guide on how to build high-performance API clients using Reactive Feign, including client options, logging, interceptor, response status, retry policy, and unit testing.
Abstract
The context begins by emphasizing the importance of non-blocking I/O in achieving high performance in API clients, especially when integrated with external APIs. It introduces OpenFeign as a popular framework for API client development but notes its lack of support for reactive clients. The context then presents feign-reactive as a recommended open-source project for creating reactive API clients.
The context covers various aspects of using feign-reactive, starting with the necessary dependency for including all required dependencies for feign reactive. It then explains how to define API client interfaces and use annotations, similar to OpenFeign. The context also covers how to customize the behavior of the API client using configuration classes, including setting timeout configuration, logging, adding API key headers using interceptors, and customizing behavior for specific response status.
The context also discusses the retry policy in case of errors and how to test feign clients using WireMock as a stub API server. The context concludes by emphasizing the importance of non-blocking technology in achieving high performance with Spring Webflux and recommends Reactive Feign for implementing non-blocking API clients.
Bullet points
Non-blocking I/O is crucial for high performance in API clients, especially when integrated with external APIs.
OpenFeign is a popular framework for API client development but lacks support for reactive clients.
Feign-reactive is a recommended open-source project for creating reactive API clients.
The necessary dependency for including all required dependencies for feign reactive is provided.
API client interfaces can be defined using annotations, similar to OpenFeign.
Configuration classes can be used to customize the behavior of the API client, including setting timeout configuration, logging, adding API key headers using interceptors, and customizing behavior for specific response status.
The retry policy can be set in case of errors.
Feign clients can be tested using WireMock as a stub API server.
Non-blocking technology is important for achieving high performance with Spring Webflux, and Reactive Feign is recommended for implementing non-blocking API clients.
How to Build High Performance API Client Using Reactive Feign
A Definitive Guide to Reactive Feign — Client Options, Logging, Interceptor, Response Status, Retry Policy and Unit Testing
Spring Webflux is a future-proof technology stack as it efficiently makes use of computing resources and achieves non-blocking I/O. The test results in my previous article prove that Spring Webflux considerably outperforms Spring Servlet (blocking technology) under a heavy workload. You will find this article useful if you would like to know how to build Spring Webflux application.
However, just because making use of Spring Webflux does not mean that the performance gain is guaranteed if I/O processes such as access to databases and integration with external APIs in your system are still based on blocking technology. For example, the system diagram illustrates a typical API integration with a 3rd party API service. The API client sends a request to the endpoint and it holds the thread until a response is received. As a result, the whole process is blocked until a response is received.
Without a doubt, it is critical to apply non-blocking in the end-to-end process so as to enjoy the benefit of Reactive technology.
The Quick Way To Create API Client
OpenFeign is a popular framework when it comes to API client development. What you need is to define the interface of the API clients, then the framework magically takes care of the rest for you.
For example, this is the API client for foreign currency rate retrieval and booking. Just the interface definition and that is.
Behind the scenes, the framework generates implementations based on configuration and injects them into your business logic. The use of OpenFeign significantly boosts productivity and enables rapid development.
Feign Reactive Client
Although the use of OpenFeign is prevalent, neither OpenFeign project nor Spring Cloud OpenFeign supports the reactive clients at the time of writing. Meanwhile, an open-source project feign-reactive is recommended by the Spring framework team until the Feign reactive client is supported as part of the Spring core project. In this article, I will show you how to create API clients using the feign reactive framework.
Dependency
Add this starter to the maven dependency, it provides a convenient way to include all required dependencies for feign reactive.
The interface definition and the use of annotations for feign reactive are similar to OpenFeign. Developers who are familiar with OpenFeign can pick up feign reactive quickly.
The reactive version of the Forex API client is exactly the same as the one based on OpenFeign except for the first annotation which is @ReactiveFeignClient instead of @FeignClient.
System behavior of the API client can be customized by defining relevant beans in the configuration class, we will go through the configuration detail in the following sections.
Spring WebClient Options
Reactive Feign comes with the default implementation based on Spring Reactive WebClient. The framework allows us to tweak the timeout configuration of the WebClient. The sample configuration below specifies 2 seconds timeout
In fact, Reactive Feign supports configuration using application.yml. The YAML below on application.yml serves the same purpose. However, gathering splitting configuration between application.yml and configuration class, centralizing all set up within a single configuration class is highly recommended for easy maintenance.
Logging
To log API requests and responses, define a bean for Reactive Logger Listener using the default reactive logger in the configuration class.
Set the logging level of the API client to TRACE
Then, the request and response including headers and body will be logged for every request
Adding API Key Header Using Interceptor
Feign Reactive allows certain customization on API requests such as the insertion of common request fields. Adding a header for the API key is the typical example. While it is tedious to add the header to every method, we can make it transparent to API calls using Interceptor.
This API client has an API key header in every method
Instead of adding the header in each client method, define interceptor bean in the configuration class, it automatically inserts X-API-KEY header for all requests.
Customize Behavior for Specific Response Status
The feign client throws a feign exception whenever a negative response is encountered, no matter if it is client reject, server error or 404.
You can alter the behavior for specific response status. This example configures ReactiveStatusHandler such that the client throws RetryableException if server error 500 is encountered so that the client will retry the operation.
Retry Policy
In case of error such as timeout, we can instruct the feign client to retry the request automatically. The sample code below sets the max retry count to be 3 with 2 seconds back off between each retry.
Unit Test of Feign Client
Feign client can be tested using WireMock as the stub API server. The sample code below starts up WireMock server as a static class object and then injects the WireMock server’s url to the system property. With the system property updated, the feign client connects to the stub API server.
The unit test is straightforward, it defines the stub API, invokes the feign client followed by result verification.
This article is a good reference if you would like to know more about WireMock
Verify Request Retries
To simulate fault and verify the feign client’s retry capability is somehow tricky. Fortunately, WireMock supports response with pre-defined delay for the simulation of timeout and stateful behavior.
Create a slow API stub with a fixed delay of 30 seconds for the 1st attempt and 2nd attempt. Then, set up the stub to respond quickly for the 3rd attempt. Supposing that the feign client should encounter timeout and the second retry should be working.
The sample code below shows how to create WireMock stub with stateful behavior
Conclusion
Spring Webflux does not contribute to performance gain if I/O processes are still based on blocking technology. Reactive Feign is great choice for the implementation of non-blocking API clients. It is a reactive version of OpenFeign which supports the creation of API clients without the need to writing implementation code. By just defining interface and configuration, development of API clients can be done effortlessly.
Refer to this GitHub project for the source code of the sample Forex API client