Cloud Native 9 min read

Unveiling Feign: How It Works, Configurations, and Advanced Tricks

This article explains Feign's internal workflow, annotation attributes, GZIP compression, logging setup, timeout handling, and strategies for passing multiple parameters in GET/POST requests, providing practical code examples for Spring Cloud microservice integration.

Java Interview Crash Guide
Java Interview Crash Guide
Java Interview Crash Guide
Unveiling Feign: How It Works, Configurations, and Advanced Tricks

Feign Working Principle

The main program enables Feign client scanning with @EnableFeignClients. During startup, Spring scans for interfaces annotated with @FeignClient, registers them in the IOC container, and creates JDK proxies that generate a RequestTemplate for each method.

The RequestTemplate encapsulates all HTTP request details (method, parameters, etc.), builds a Request, and hands it to a client implementation (e.g., JDK URLConnection, Apache HttpClient, or OkHttp). The client is wrapped by LoadBalanceClient, which uses Ribbon for load‑balanced service calls.

Feign Annotation Breakdown

name : specifies the Feign client name, used as the service identifier for Ribbon discovery.

url : optional address for debugging or direct calls.

decode404 : when true, a 404 response is passed to the decoder instead of throwing an exception.

configuration : custom configuration class to override encoder, decoder, log level, contract, etc.

fallback : class implementing the Feign interface to provide a fallback when the remote call fails or times out.

fallbackFactory : factory to create fallback instances, allowing shared fallback logic.

path : common prefix for all requests of the client.

Enabling GZIP Compression

Spring Cloud Feign can compress requests and responses via GZIP. Add the following YAML configuration:

feign:
  compression:
    request:
      enabled: true
      mimeTypes: text/xml,application/xml,application/json
      minRequestSize: 2048
    response:
      enabled: true

When compression is enabled, responses must be received as ResponseEntity<byte[]> to handle binary data.

@FeignClient(name = "github-client", url = "https://api.github.com", configuration = HelloFeignServiceConfig.class)
public interface HelloFeignService {
    @RequestMapping(value = "/search/repositories", method = RequestMethod.GET)
    ResponseEntity<byte[]> searchRepositories(@RequestParam("q") String parameter);
}

Feign Client Logging

Define a configuration class to set the logger level to FULL:

@Configuration
public class HelloFeignServiceConfig {
    /**
     * Logger.Level options:
     * NONE – no logging
     * BASIC – method, URL, status, time
     * HEADERS – includes request/response headers
     * FULL – logs headers, body, and metadata
     */
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

Timeout Settings

Feign calls involve Ribbon and optionally Hystrix. Configure Ribbon timeouts as needed:

# Request processing timeout
ribbon.ReadTimeout: 12000
# Connection timeout
ribbon.ConnectionTimeout: 30000

If Hystrix is enabled, adjust its circuit‑breaker and execution settings:

hystrix:
  command:
    default:
      circuitBreaker:
        sleepWindowInMilliseconds: 30000
        requestVolumeThreshold: 50
      execution:
        timeout:
          enabled: true
      isolation:
        strategy: SEMAPHORE
        semaphore:
          maxConcurrentRequests: 50
        thread:
          timeoutInMilliseconds: 100000

Handling Multiple Parameters in GET/POST

Feign does not fully support Spring MVC's automatic POJO binding for GET requests. Workarounds include:

Manually list each POJO field as a separate request parameter.

Convert parameters into a Map.

Use @RequestBody on a POJO (breaks RESTful conventions).

A request interceptor can transform a JSON body into query parameters for GET requests:

@Component
public class FeignRequestInterceptor implements RequestInterceptor {
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void apply(RequestTemplate requestTemplate) {
        // Feign does not support POJO for GET, convert JSON body to query
        if (requestTemplate.method().equalsIgnoreCase("GET") && requestTemplate.body() != null) {
            try {
                JsonNode jsonNode = objectMapper.readTree(requestTemplate.body());
                requestTemplate.body(null);
                Map<String, Collection<String>> queries = new HashMap<>();
                buildQuery(jsonNode, "", queries);
                requestTemplate.queries(queries);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void buildQuery(JsonNode jsonNode, String path, Map<String, Collection<String>> queries) {
        if (!jsonNode.isContainerNode()) {
            if (jsonNode.isNull()) return;
            Collection<String> values = queries.computeIfAbsent(path, k -> new ArrayList<>());
            values.add(jsonNode.asText());
            return;
        }
        if (jsonNode.isArray()) {
            jsonNode.elements().forEachRemaining(node -> buildQuery(node, path, queries));
        } else {
            jsonNode.fields().forEachRemaining(entry -> {
                String newPath = path.isEmpty() ? entry.getKey() : path + "." + entry.getKey();
                buildQuery(entry.getValue(), newPath, queries);
            });
        }
    }
}

An alternative is to use the venus-cloud-feign library, which automatically wraps GET parameters into a map:

<!-- https://mvnrepository.com/artifact/cn.springcloud.feign/venus-cloud-feign-core -->
<dependency>
    <groupId>cn.springcloud.feign</groupId>
    <artifactId>venus-cloud-feign-core</artifactId>
    <version>1.0.0</version>
</dependency>

Repository: https://github.com/SpringCloud/venus-cloud-feign.git

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavafeignSpring CloudHystrixHTTP clientRibbon
Java Interview Crash Guide
Written by

Java Interview Crash Guide

Dedicated to sharing Java interview Q&A; follow and reply "java" to receive a free premium Java interview guide.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.