Usage

About

Feign is a declarative HTTP client that allows developers to write clean, type-safe interfaces to call remote HTTP services in a Spring-based application. Rather than writing boilerplate code for HTTP requests, Feign enables us to define Java interfaces annotated with Spring MVC annotations (@GetMapping, @PostMapping, etc.), and it takes care of the rest.

This is especially useful in microservices where services frequently communicate over REST. It promotes better abstraction, reusability, and readability.

Dependency

To use Feign in a Spring Boot application, add the following dependency:

If we’re using Spring Cloud OpenFeign:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

Also, make sure to include the appropriate Spring Cloud BOM in our dependencyManagement:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2023.0.1</version> <!-- Replace the version -->
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Compatibility

Feature
Compatibility

Spring Boot

Fully compatible with Spring Boot 2.x and 3.x

Spring Cloud

Required. Feign is integrated via Spring Cloud OpenFeign

Spring WebMVC

Native support using Spring MVC-style annotations

WebFlux

Not recommended. Feign is blocking and not reactive

OpenAPI

Not directly integrated. OpenAPI-generated clients are better suited for spec-first development

Declarative API

OpenFeign follows a declarative programming model we define what the client interface should look like, and the library generates the HTTP call logic at runtime. Unlike RestTemplate or WebClient, we don't explicitly construct HTTP requests in a fluent chain. Instead, we declare how to reach a service using Java interfaces and annotations.

This approach leads to cleaner, more concise, and maintainable code — especially in large enterprise applications where service-to-service communication is frequent.

Declarative API Style

Declarative means we describe the desired behavior (the what), not the process (the how). With Feign, the focus is on interface-first programming.

@FeignClient(name = "user-service", url = "http://localhost:8081")
public interface UserClient {

    @GetMapping("/api/users/{id}")
    UserDto getUser(@PathVariable("id") Long id);

    @PostMapping("/api/users")
    UserDto createUser(@RequestBody UserDto user);
}

We are not writing the logic to build the request, set headers, parse the response, or handle connection issues Feign generates that code based on annotations.

How It Differs from Fluent API (e.g., WebClient)

Aspect
Declarative (Feign)
Fluent (WebClient)

Programming Style

Interface-based with annotations

Code-based chain of method calls

HTTP Verb Configuration

Annotated on method (@GetMapping, @PostMapping, etc.)

Explicitly called (.get(), .post() etc.)

URL & Path

Declared in interface and method-level mapping

Built using .uri(...) and path/query params

Headers, Cookies

Declared via annotations or interceptors

Set dynamically in the fluent chain

Control Flow

Abstracted away

Developer fully controls request/response logic

Type Safety

Strong — compile-time checks via interface

Moderate — dynamic object mapping via lambdas

Common Use

Simpler synchronous REST clients

Advanced or reactive usage (streaming, backpressure, etc.)

Creating a OpenFeign Instance

In OpenFeign, we don’t create an instance manually like we would with WebClient or RestTemplate. Instead, we define an interface, annotate it with @FeignClient, and Spring Boot (via Spring Cloud OpenFeign) automatically generates the implementation at runtime and registers it as a Spring bean.

This promotes clean separation of concerns and allows us to inject the client wherever needed just like any other Spring-managed dependency.

How It Works ?

To create and use a Feign client:

  1. Define an interface

  2. Annotate with @FeignClient

  3. Use Spring’s dependency injection to autowire the client

Example

Step 1: Enable Feign Support

@SpringBootApplication
@EnableFeignClients
public class PaymentServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(PaymentServiceApplication.class, args);
    }
}

Step 2: Define the Feign Client Interface

@FeignClient(name = "account-service", url = "http://localhost:8081")
public interface AccountClient {

    @GetMapping("/api/accounts/{id}")
    AccountDto getAccountById(@PathVariable("id") Long id);
}

Step 3: Use the Client in a Service

@Service
public class PaymentService {

    private final AccountClient accountClient;

    public PaymentService(AccountClient accountClient) {
        this.accountClient = accountClient;
    }

    public void processPayment(Long accountId) {
        AccountDto account = accountClient.getAccountById(accountId);
        // use account info...
    }
}

Last updated