Feign is a declarative REST client in Spring Cloud that makes writing web service clients easier. Instead of writing boilerplate RestTemplate
or WebClient
code, you define an interface and annotate it — Spring generates the implementation for you at runtime.
Here’s a step-by-step example of using Feign Client in Spring Boot:
1. Add dependencies
In your pom.xml
(Maven):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2023.0.1</version> <!-- check latest version -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
For Gradle:
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:2023.0.1"
}
}
2. Enable Feign Clients
In your Spring Boot main application class:
@SpringBootApplication
@EnableFeignClients
public class FeignDemoApplication {
public static void main(String[] args) {
SpringApplication.run(FeignDemoApplication.class, args);
}
}
3. Create a Feign Client Interface
Suppose we want to call an external REST API (like JSONPlaceholder).
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
@FeignClient(name = "jsonPlaceholderClient", url = "https://jsonplaceholder.typicode.com")
public interface JsonPlaceholderClient {
@GetMapping("/posts")
List<Post> getPosts();
@GetMapping("/posts/{id}")
Post getPostById(@PathVariable("id") Long id);
}
4. Create a Model Class
public class Post {
private Long userId;
private Long id;
private String title;
private String body;
// getters and setters
}
5. Use Feign Client in a Service
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class PostService {
private final JsonPlaceholderClient jsonPlaceholderClient;
public PostService(JsonPlaceholderClient jsonPlaceholderClient) {
this.jsonPlaceholderClient = jsonPlaceholderClient;
}
public List<Post> getAllPosts() {
return jsonPlaceholderClient.getPosts();
}
public Post getPostById(Long id) {
return jsonPlaceholderClient.getPostById(id);
}
}
6. Expose via Controller
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class PostController {
private final PostService postService;
public PostController(PostService postService) {
this.postService = postService;
}
@GetMapping("/posts")
public List<Post> getPosts() {
return postService.getAllPosts();
}
@GetMapping("/posts/{id}")
public Post getPostById(@PathVariable Long id) {
return postService.getPostById(id);
}
}
7. Run and Test
Start the Spring Boot application and test:
http://localhost:8080/posts
→ returns list of postshttp://localhost:8080/posts/1
→ returns single post
✨ That’s it — you now have a working Feign client in Spring Boot!
Do you want me to also show you how to add fallback handling (Resilience4j/Hystrix) for Feign in case the external API is down?