A Guide to Spring Cloud OpenFeign

Spring Cloud OpenFeign is a declarative HTTP client provided by the Spring Cloud ecosystem. It allows you to write web service clients by defining Java interfaces, abstracting away the need for manually writing REST client code using RestTemplate or WebClient.

In this post, I will cover common uses of Spring Cloud OpenFeign. This post is based on Java 21, Spring Boot 3.5.3, and Spring Cloud 2025.0.0.

1. Create Project and Add Dependencies

Using Gradle

$ mkdir spring-cloud-open-feign && cd spring-cloud-open-feign
$ gradle --configuration-cache \
init --use-defaults \
--type java-application \
--package com.taogen.springcloud

app/build.gradle.kts

plugins {
java
id("org.springframework.boot") version "3.5.3"
// Use the Spring Dependency Management plugin to manage Spring Cloud dependencies.
id("io.spring.dependency-management") version "1.1.7"
}

extra["springCloudVersion"] = "2025.0.0"

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}

repositories {
mavenCentral()
}

dependencies {
implementation("org.springframework.cloud:spring-cloud-starter-openfeign")
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-actuator")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

dependencyManagement {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
}
}

tasks.withType<Test> {
useJUnitPlatform()
}

Using Maven

$ mvn -B archetype:generate \
-DgroupId=com.taogen.springcloud \
-DartifactId=spring-cloud-open-feign \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.5

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.taogen.springcloud</groupId>
<artifactId>spring-cloud-open-feign</artifactId>
<version>1.0-SNAPSHOT</version>

<name>spring-cloud-open-feign</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>21</maven.compiler.release>
<java.version>21</java.version>
<spring-boot.version>3.5.3</spring-boot.version>
<spring-cloud.version>2025.0.0</spring-cloud.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

Using Spring Initializr

Go to https://start.spring.io/

Project Metadata

  • Group: com.taogen.springcloud
  • Artifact: spring-cloud-open-feign

Add dependencies

  • OpenFeign
  • Eureka Discovery Client
  • Spring Web
  • Spring Boot Actuator

2. Spring Configuration

It’s the same as the Eureka client spring configuration.

application.yml

spring:
application:
name: spring-cloud-open-feign
eureka:
instance:
preferIpAddress: true
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/
healthcheck:
enabled: true
server:
# configure the service to use a random port number
port: 0
management:
endpoints:
web:
exposure:
include: health,info,beans

3. The Application

1. Spring Boot application entry point

SpringCloudOpenFeignApplication.java

package com.taogen.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class SpringCloudOpenFeignApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudOpenFeignApplication.class, args);
}
}
  • @EnableFeignClients: To enable Open Feign.

2. Define a Feign Client interface with @FeignClient

GreetingClient.java

package com.taogen.springcloud;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient("eureka-client-2")
public interface GreetingClient {
@GetMapping("/greeting")
String greeting();
}

3. Using the Feign Client

package com.taogen.springcloud;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/")
public class MyController {
private final GreetingClient greetingClient;

public MyController(GreetingClient greetingClient) {
this.greetingClient = greetingClient;
}

@RequestMapping("/callEurekaClient2UsingOpenFeign")
public String callEurekaClient2UsingOpenFeign() {
return greetingClient.greeting();
}
}

4. Start and Verification

1. Starting a Eureka server and two instances of Eureka-Client-2. And write a greeting API in Eureka-Client-2. For using Eureka, you can refer to A Guide to Spring Cloud Netflix Eureka.

The greeting API in Eureka Client 2

@RestController  
@RequestMapping("/")
public class MyController {
@Value("${spring.application.name}")
private String applicationName;

@GetMapping("/greeting")
public String greeting(){
System.out.println("greeting method is called");
return "Hello from " + applicationName + new Date();
}
}

Starting two instances of Eureka-Client-2 with the following command. Running the command in two terminal tabs to start two instances.

Gradle

./gradlew bootRun

Maven

mvn spring-boot:run

2. Running the main() method in the SpringCloudOpenFeignApplication to start this Spring Cloud OpenFeign application.

3. Request the /callEurekaClient2UsingOpenFeign endpoint to see the result of using a client-side load balancer to call Eureka client 2 instances.

References

[1] Spring Microservices in Action, Second Edition

[2] Spring Cloud OpenFeign Documentation