Feign is a declarative HTTP client. GitHub: https://github.com/OpenFeign/feign
Simple Usage
Add the dependency:
| |
Add the annotation to the startup class to enable Feign:
| |
Create a Feign client:
| |
Replace RestTemplate:
| |
Custom Configuration
Feign allows custom configurations to override defaults. Key configurations include:
| Type | Function | Description |
|---|---|---|
| feign.Logger.Level | Modify log level | Four levels: NONE, BASIC, HEADERS, FULL |
| feign.codec.Decoder | Response decoder | Parses HTTP call results, e.g., JSON string to Java object |
| feign.codec.Encoder | Request encoder | Encodes request parameters for HTTP transmission |
| feign. Contract | Annotation format | Defaults to SpringMVC annotations |
| feign. Retryer | Retry mechanism | Retry logic for failed requests; default is none, but uses Ribbon’s retry |
Usually, you only need to configure the log level. Levels include:
- NONE: No logging (default).
- BASIC: Logs only the request method, URL, response status code, and execution time.
- HEADERS: BASIC plus request and response headers.
- FULL: Logs everything—headers, body, and metadata for both request and response.
There are two ways to configure this: via configuration files or by creating a Bean.
Configuration File
For a specific service:
| |
Global configuration for all services:
| |
Bean Configuration
First, define a configuration class and declare a Logger.Level Bean:
| |
To apply it globally, add it to the @EnableFeignClients annotation in the startup class:
| |
To apply it to a specific service, add it to the @FeignClient annotation:
| |
Feign Optimization
Feign’s underlying HTTP client implementations:
- URLConnection: Default, no connection pooling.
- Apache HttpClient: Supports connection pooling.
- OKHttp: Supports connection pooling.
Using a connection pool improves performance. Here is how to switch to HttpClient:
- Add the dependency:
| |
- Configure the connection pool:
| |
Best Practices
Best practices are optimized approaches based on common usage patterns.
The Feign client code often mirrors the provider’s controller:
| |
There are two ways to simplify this duplication:
Method 1: Inheritance
Define a common interface for both the consumer’s FeignClient and the provider’s Controller.
Define the interface:
| |
Feign Client implementation:
| |
Controller implementation:
| |
Pros: Simple and achieves code sharing.
Cons:
- Tight coupling between provider and consumer.
- Annotation mapping in parameter lists doesn’t inherit; you must redeclare methods, parameters, and annotations in the Controller.
Method 2: Extraction (Modularization)
Extract FeignClient into a standalone module. Place the interface, related POJOs, and default Feign configurations in this module for all consumers to use.
Create a new project and add the Feign starter dependency:
| |
Import this feign-api dependency into the consumer project.
If the defined FeignClient is outside the scanning range of the SpringBootApplication, it won’t be picked up. Fix this in two ways:
- Specify the package to scan:
| |
- Specify the specific client classes to load:
| |