Use Feign for interface calls between microservices: declarative service calls in Spring Cloud Alibaba

1. Introduction of Feign

        Feign is a declarative HTTP client framework for simplifying communication between services in a microservices architecture. It is part of the Spring Cloud framework and aims to provide an elegant and easy-to-use way to define and invoke HTTP requests.

        Feign's design goal is to make communication between services easier and more intuitive. Typically, in a microservices architecture, one service needs to call another service's API to fetch data or perform an operation. In the traditional way, we need to manually write HTTP requests, process requests and responses, and the emergence of Feign simplifies this process.

        Using Feign, you only need to define an interface to describe the API of the service to be called, and then configure the processing method of requests and responses through annotations. Feign will automatically generate available HTTP requests according to the interface definition, send the request to the target service, and convert the response into an appropriate object type to return.

Feign has the following features and advantages:

  1. Declarative API definition: By simply defining the interface, the communication between services can be clearly described without having to pay attention to the underlying HTTP details.
  2. Built-in load balancing support: Feign is integrated with Spring Cloud's service registration and discovery mechanism, which can automatically implement load balancing and easily handle service calls from multiple instances.
  3. Automatic serialization and deserialization of requests and responses: Feign can automatically handle serialization and deserialization of requests and responses, enabling you to manipulate data in an object-oriented manner.
  4. Integrated service fusing and current limiting: Feign integrates with Spring Cloud's fuses (such as Hystrix) and current limiters (such as Sentinel), which can provide service fusing and current limiting capabilities, increasing the stability and reliability of the system.
  5. Easy to extend: Feign provides a pluggable mechanism that allows you to extend and customize its behavior through custom configurations and interceptors.

 Second, the use of Feign

Here I take the pig project as an example for illustration. Project address: https://gitee.com/log4j/pig

1. Description of project modules

pig 
├── pig-auth -- authorization service provision [3000] 
└── pig-common -- system common module 
     ├── pig-common-bom -- global dependency management control 
     ├── pig-common-core -- Common tools core package 
     ├── pig-common-datasource -- dynamic data source package 
     ├── pig-common-job -- xxl-job package 
     ├── pig-common-log -- log service 
     ├── pig- common-mybatis -- mybatis extension package 
     ├── pig-common-seata -- distributed transactions 
     ├── pig-common-security -- security tools 
     ├── pig-common-swagger -- interface documentation 
     ├── pig -common-feign -- feign extension package 
     └── pig-common-xss -- xss security package 
├── pig-register -- Nacos Server[8848] 
├── pig-gateway -- Spring Cloud Gateway[9999]  
└── pig-upms -- general user rights management module
     └── pig-upms-api -- general user rights management system public api module
     └── pig-upms-biz -- general user rights management system business processing module[4000] 
└── pig-visual 
     └── pig-monitor -- service monitoring[5001] 
     ├── pig-codegen -- graphical Code generation[5002] 
     ├── pig-sentinel-dashboard -- traffic high availability[5003] 
     └── pig-xxl-job-admin -- distributed timing task management console[5004]

 2. Feign client definition

(1) Introduce Feign dependency

Both the pig-upms-api module and the pig-upms-biz module need to introduce feign dependencies:

        <!--feign 注解依赖-->
        <dependency>
            <groupId>com.pig4cloud</groupId>
            <artifactId>pig-common-feign</artifactId>
            <optional>true</optional>
        </dependency>

(2) Define the location

        As you can see in the code, Feign's client is defined in the pig-upms-api module. It is a common design pattern to define Feign's client under the pig-upms-api module. The purpose of this mode is to define Feign's client interface as a part of the API module, so that other modules can use the API by introducing pig-upms-api dependencies, and realize the connection with the pig-upms-biz module (general user The communication between the business processing module of the rights management system).

 (3) Feign client definition

Take RemoteUserService as an example:

//标识这是一个Feign客户端接口,contextId指定客户端的id,用于和其他客户端区分
//value="pig-upms-biz" 指定了要调用的服务名称
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.UMPS_SERVICE)
public interface RemoteUserService {


	//通过用户名查询用户、角色信息

	//@GetMapping注解指定了要调用的HTTP GET请求的路径。这里是 /user/info/{username}
	//headers指定了请求的头部信息,这里HEADER_FROM_IN的值是"from=Y"
	@GetMapping(value = "/user/info/{username}", headers = SecurityConstants.HEADER_FROM_IN)
	R<UserInfo> info(@PathVariable("username") String username);

	//通过手机号码查询用户、角色信息
	@GetMapping(value = "/app/info/{phone}", headers = SecurityConstants.HEADER_FROM_IN)
	R<UserInfo> infoByMobile(@PathVariable("phone") String phone);
	
	//根据部门id,查询对应的用户 id 集合
	@GetMapping(value = "/user/ids", headers = SecurityConstants.HEADER_FROM_IN)
	R<List<Long>> listUserIdByDeptIds(@RequestParam("deptIds") Set<Long> deptIds);

}

Actually this Feign client will send request to SysUserController :

 (4) Test in other modules

For example, if I want to use Feign to make interface calls under the pig-codegen module, I need to introduce the pig-upms-api dependency in the codegen module first, because we define the Feign client under pig-upms-api.

        <!--upms api、model 模块-->
        <dependency>
            <groupId>com.pig4cloud</groupId>
            <artifactId>pig-upms-api</artifactId>
        </dependency>

Write a test Controller:

@RestController
@RequiredArgsConstructor  //自动生成构造方法,在生成FeignDemoController会将remoteUserService传入
@RequestMapping("/feignDemo")
public class FeignDemoController {

	//注入Feign客户端接口 RemoteUserService
	//定义为final 确保在实例化后变量不会发生意外改变
	private final RemoteUserService remoteUserService;

	@Inner(value = false)
	@GetMapping("/test")
	public R<UserInfo> test() {
		//假设传入的用户名是 admin
		String username = "admin";
		//调用feign中的info方法
		return remoteUserService.info(username);
	}
}

Start the service test, and you can see that the information of the admin user has been successfully obtained:

Supplement: Regarding the understanding of the two injection methods:

When injecting remoteUserServiceproperties, you can use @RequiredArgsConstructorannotations or @Autowiredannotations in two ways. The two methods have the following differences:

  1. @RequiredArgsConstructor: When using the annotation on a class @RequiredArgsConstructor, it will automatically generate a constructor for you, which will be remoteUserServicepassed in as a parameter and injected. This approach is to inject dependencies through constructors . Using @RequiredArgsConstructorannotations can simplify the code and reduce the work of manually writing constructors.

  2. @Autowired: When an annotation is used on a property @Autowired, it automatically injects an instance of the corresponding type into the property. This way is to inject dependencies through fields. The Spring framework will automatically scan and find RemoteUserServicean instance that matches the type, and inject it into remoteUserServicethe property. @AutowiredDependency injection can be easily done using annotations, but you need to ensure that the required instances exist and are unique.

In general, the effects of these two injection methods are the same, and both will be RemoteUserServiceinjected into remoteUserServicethe property. The choice of which to use depends on preference and conventions in your project. Using @RequiredArgsConstructorcan provide more concise code, while using @Autowiredis more flexible and can adapt to more different scenarios.

Guess you like

Origin blog.csdn.net/weixin_49561506/article/details/131653796