Backend Development 11 min read

Master Spring Cloud OpenFeign: Complete Guide with Code Samples

This article provides a comprehensive introduction to Spring Cloud OpenFeign, comparing it with Feign and HttpExchange, and walks through practical setup, client declaration, custom configuration, interceptors, error handling, timeout and logging settings with full code examples for Spring Boot 3.2.5.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master Spring Cloud OpenFeign: Complete Guide with Code Samples

1. Introduction

OpenFeign is a declarative HTTP client that simplifies writing network service clients. By annotating an interface, you can call other services without writing boilerplate code. It supports both OpenFeign and Jakarta JAX‑RS annotations.

The article offers a full‑stack overview of Spring Cloud OpenFeign.

2. Practical Example

2.1 Add Dependency

<code>&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
  &lt;artifactId&gt;spring-cloud-starter-openfeign&lt;/artifactId&gt;
  &lt;version&gt;2022.0.3&lt;/version&gt;
&lt;/dependency&gt;</code>

Choose the Cloud version that matches your Spring Boot version.

2.2 Enable Feign Clients

<code>@SpringBootApplication
@EnableFeignClients(basePackages = "com.pack.feign")
public class AppApplication {
}
</code>

If the annotation is placed on the main class, the basePackages attribute can be omitted.

2.3 Declare Feign Client

<code>@FeignClient(value = "userFeignClient", url = "http://localhost:8088")
public interface UserFeignClient {
    @GetMapping("/users")
    ResponseEntity&lt;List&lt;User&gt;&gt; getUsers();
}
</code>

value specifies the client name (required). url defines the base request URL. The @GetMapping annotation maps the target endpoint.

2.4 Invoke the Client

<code>private final UserFeignClient userFeignClient;
public UserFeignController(UserFeignClient userFeignClient) {
    this.userFeignClient = userFeignClient;
}
ResponseEntity&lt;List&lt;User&gt;&gt; response = userFeignClient.getUsers();
if (response.getStatusCode().is2xxSuccessful()) {
    List&lt;User&gt; users = response.getBody();
    users.forEach(System.out::println);
} else if (response.getStatusCode().is4xxClientError()) {
    throw new BadRequestException("Bad Request");
} else {
    throw new RuntimeException("Server Error");
}
</code>

The client is injected like any other Spring bean.

2.5 Inheritance

Common functionality can be placed in a base interface and extended:

<code>@FeignClient(value = "accountFeignClient", url = "http://localhost:8088/")
public interface AccountFeignClient extends UserFeignClient {
    @GetMapping("/account/{id}")
    String getAccountByUser(@PathVariable("id") Long id);
}
</code>

Multi‑level inheritance is not supported.

2.6 OpenFeign Configuration

Default components are defined in FeignClientsConfiguration and can be overridden.

Decoder – ResponseEntityDecoder (wraps SpringDecoder )

Encoder – SpringEncoder

Logger – Slf4jLogger

Contract – SpringMvcContract

Retryer – configurable retry strategy

Client – global request handler

Custom configuration example:

<code>public class PackAccountFeignConfiguration {
    @Bean
    public CloseableHttpClient feignClient() {
        return HttpClients.createDefault();
    }
}
</code>

Use the custom configuration in the client annotation:

<code>@FeignClient(value = "accountFeignClient",
             url = "http://localhost:8088/",
             configuration = PackAccountFeignConfiguration.class)
public interface AccountFeignClient extends UserFeignClient {}
</code>

Add the required dependency for the Apache HttpClient:

<code>&lt;dependency&gt;
  &lt;groupId&gt;io.github.openfeign&lt;/groupId&gt;
  &lt;artifactId&gt;feign-hc5&lt;/artifactId&gt;
&lt;/dependency&gt;
</code>

2.7 Property‑Based Configuration

Override settings via application.yml :

<code>spring:
  cloud:
    openfeign:
      config:
        default:
          connectTimeout: 5000
          read-timeout: 5000
</code>

Specific client configuration:

<code>spring:
  cloud:
    openfeign:
      config:
        accountFeignClient:
          connectTimeout: 5000
</code>

When both a @Configuration bean and properties are present, properties take precedence unless spring.cloud.openfeign.client.default-to-properties is set to false .

2.8 Interceptor Configuration

<code>@Bean
RequestInterceptor requestInterceptor() {
    return template -> template.header("requestID", "UUID");
}
</code>

Allows adding custom headers or authentication logic.

2.9 Error Handling

<code>@Bean
ErrorDecoder errorDecoder() {
    return (methodKey, response) -> switch (response.status()) {
        case 400 -> new BadRequestException(response);
        case 429 -> new TooManyRequestsException(response);
        default -> new Exception("feign client exception");
    };
};
</code>

Provides fine‑grained exception handling based on HTTP status.

2.10 Logging

Enable logging via properties:

<code>logging:
  level:
    com.pack.feign: DEBUG
</code>

Or for a specific client:

<code>logging:
  level:
    com.pack.feign.AccountFeignClient: DEBUG
</code>

Define logger level bean for full logging:

<code>@Bean
Logger.Level feignLoggerLevel() {
    return Logger.Level.FULL;
}
</code>

Supported levels: NONE, BASIC, HEADERS, FULL.

JavamicroservicesSpring BootOpenFeignFeignClient
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login 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.