Spring Boot 3 with Feign Client
Feign Client is a declarative web service client. It simplifies the process of making HTTP requests to other services by abstracting the complexities of RESTful API calls. 0 commentsBy Sopheaktra Eang | August 27, 2024
The fully fledged server uses the following:
- Spring Framework
- SpringBoot
- Spring Cloud
- Feign Client
- Lombok
There are a number of third-party dependencies used in the project. Browse the Maven pom.xml file for details of libraries and versions used.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
for spring cloud import pom of spring cloud
<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>
</dependencies>
</dependencyManagement>
Key Features of Feign Client:
-
Declarative REST Client: With Feign, you define a Java interface that maps to a remote service. Feign generates the implementation at runtime and handles the HTTP communication.
-
Integration with Spring Cloud: Feign integrates seamlessly with Spring Cloud, allowing it to work with various components like Eureka for service discovery, Ribbon for client-side load balancing, and Hystrix for circuit breaking.
-
Declarative Configuration: You can configure headers, request parameters, and even the HTTP method using simple annotations.
-
Support for Load Balancing and Fault Tolerance: Feign can be integrated with Ribbon for client-side load balancing and Hystrix for fault tolerance, enabling retries, fallback methods, and circuit breakers.
-
Easy Integration with RESTful APIs: Feign makes it easy to consume RESTful APIs by simply defining methods in an interface, similar to defining Spring MVC controller methods.
Advanced Features:
-
Custom Configuration: You can customize the Feign client by specifying a custom configuration class. This can include setting timeouts, encoding/decoding, logging, and more.
-
Hystrix Integration: By integrating Hystrix, you can add circuit breakers and fallback methods to your Feign clients, enhancing the resilience of your application.
-
Load Balancing with Ribbon: When combined with Ribbon, Feign can automatically distribute requests among multiple instances of a service.
Enable Feign Clients:
package com.tra21.feign_client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class FeignClientApplication {
public static void main(String[] args) {
SpringApplication.run(FeignClientApplication.class, args);
}
}
Define a Feign Client Interface:
package com.tra21.feign_client.configurations.feigns;
import com.tra21.feign_client.dtos.requests.FilterListDto;
import com.tra21.feign_client.dtos.requests.users.CreateUserRequestDto;
import com.tra21.feign_client.dtos.requests.users.UpdateUserRequestDto;
import com.tra21.feign_client.dtos.responses.users.UserResponseDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@FeignClient(name = "fakestoreapi-users", url = "https://fakestoreapi.com", path = "/users")
public interface UserFakeAPIStoreFeignClient {
@GetMapping
List<UserResponseDto> getUsers(FilterListDto filterListDto);
@GetMapping("/{id}")
UserResponseDto getUserById(@PathVariable("id") int id);
@PostMapping
UserResponseDto createUser(@RequestBody CreateUserRequestDto createUserRequestDto);
@PutMapping("/{id}")
UserResponseDto updateUser(@PathVariable("id") int id, @RequestBody UpdateUserRequestDto updateUserRequestDto);
@DeleteMapping("/{id}")
UserResponseDto deleteUser(@PathVariable("id") int id);
}
Use the Feign Client:
package com.tra21.feign_client.controllers;
import com.tra21.feign_client.configurations.feigns.UserFakeAPIStoreFeignClient;
import com.tra21.feign_client.dtos.requests.FilterListDto;
import com.tra21.feign_client.dtos.requests.users.CreateUserRequestDto;
import com.tra21.feign_client.dtos.requests.users.UpdateUserRequestDto;
import com.tra21.feign_client.dtos.responses.users.UserResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserAPIController {
private final UserFakeAPIStoreFeignClient userFakeAPIStoreFeignClient;
@GetMapping
public ResponseEntity<List<UserResponseDto>> getUsers(FilterListDto filterListDto){
return ResponseEntity.ok(this.userFakeAPIStoreFeignClient.getUsers(filterListDto));
}
@GetMapping("/{id}")
public ResponseEntity<UserResponseDto> getUserById(@PathVariable("id") int id){
return ResponseEntity.ok(this.userFakeAPIStoreFeignClient.getUserById(id));
}
@PostMapping
public ResponseEntity<UserResponseDto> createUser(@RequestBody CreateUserRequestDto createUserRequestDto){
return ResponseEntity.status(HttpStatus.CREATED).body(this.userFakeAPIStoreFeignClient.createUser(createUserRequestDto));
}
@PutMapping("/{id}")
public ResponseEntity<UserResponseDto> updateUser(@PathVariable("id") int id, @RequestBody UpdateUserRequestDto updateUserRequestDto){
return ResponseEntity.ok(this.userFakeAPIStoreFeignClient.updateUser(id, updateUserRequestDto));
}
@DeleteMapping("/{id}")
public ResponseEntity<UserResponseDto> deleteUser(@PathVariable("id") int id){
return ResponseEntity.ok(this.userFakeAPIStoreFeignClient.deleteUser(id));
}
}
You will need:
- Java JDK 17 or higher
- Maven 3.5.1 or higher
- Tomcat 10.1
Clone the project and use Maven to build the server
$ mvn clean install
http://localhost:8080/swagger-ui/index.html
Summary
Feign simplifies REST client creation in Spring Boot by providing a declarative interface for HTTP communication. It integrates well with Spring Cloud for service discovery, load balancing, and fault tolerance, making it a powerful tool for building microservices. Download the source code for the sample.