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 comments
By Sopheaktra Eang | August 27, 2024

Requirements

The fully fledged server uses the following:

  • Spring Framework
  • SpringBoot
  • Spring Cloud
  • Feign Client
  • Lombok

Dependencies

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>
 

Dependencies Management

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));
    }
}

 

Building the project

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
 

Swagger URL

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.