Feign is a declarative web service client that simplifies the process of making HTTP requests in a Spring Boot application. It allows you to define a Java interface and annotate it with mappings to REST endpoints, making the code more readable and maintainable. Feign integrates seamlessly with Spring Cloud, providing a powerful tool for microservice communication.
Benefits of Using Feign:
- Declarative Syntax: Define REST clients using simple annotations.
- Integration with Spring Cloud: Works well with other Spring Cloud components like Eureka and Ribbon.
- Error Handling: Provides built-in mechanisms for handling errors.
- Load Balancing: Supports client-side load balancing with Ribbon.
- Customizable: Easily extendable with custom configurations and interceptors.
Example: Spring Boot Application with Feign Client
In this tutorial we will modify an existing Spring Cloud application which we discuss in detail in this article: Getting started with Spring Cloud: Service Discovery
The application currently uses RESTTemplate to access the UserService. Let’s introduce Feign to simplify the HTTP Client for the UserService.
1. Update the card-service
Dependencies: Add the spring-cloud-starter-openfeign
dependency to your pom.xml
:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
Feign Client Interface: Define the Feign client interface to communicate with user-service
:
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @FeignClient(name = "user-service") public interface UserServiceProxy { @PostMapping("/registration") ResponseEntity<User> registerUser(@RequestBody CardApplicationDto.User userDto); }
As you can see from the above code, the UserServiceProxy
maps the method registerUser
to register an User via the UserService.
Service Class: Then, implement the service class that uses the Feign client:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @Component public class UserServiceClient { @Autowired private UserServiceProxy feignProxy; public ResponseEntity<User> registerUser(CardApplicationDto.User userDto) { return feignProxy.registerUser(userDto); } }
Application Class: Finally, enable Feign clients in the main application class:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableFeignClients public class CardServiceApplication { public static void main(String[] args) { SpringApplication.run(CardServiceApplication.class, args); } }
2. Check the user-service
The implementation of the UserRegistrationController does not need any change. For the sake of completeness, we will show here the target Controller that we are connecting with from the Feign Client:
import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/registration") public class UserRegistrationController { private final UserRegistrationService userRegistrationService; public UserRegistrationController(UserRegistrationService userRegistrationService) { this.userRegistrationService = userRegistrationService; } @PostMapping public ResponseEntity<User> registerUser(@RequestBody UserDto userDto) { User user = userRegistrationService.registerUser(userDto); return ResponseEntity.ok(user); } }
Conclusion
Using Feign in a Spring Boot application simplifies the process of making HTTP requests between microservices. By defining a Feign client interface and annotating it with REST mappings, you can easily communicate with other services in a declarative manner. This example demonstrates how to set up a card-service
that calls a user-service
using Feign, making the code more readable and maintainable.