Gọi service qua OpenFeign
govex-cloud-feign cung cấp annotation @AuthorizedFeignClient và bộ cấu hình sẵn cho OpenFeign: tự động chuyển tiếp access token cùng organization context khi service gọi service khác, và chuẩn hoá lỗi trả về từ provider thành ServiceException giữ nguyên mã lỗi nghiệp vụ.
Khi nào sử dụng
- Service cần gọi REST API của service khác trong hệ sinh thái qua OpenFeign.
- Cần forward
Authorizationtoken của người dùng hiện tại sang service đích thay vì tự viếtRequestInterceptor. - Muốn lỗi nghiệp vụ từ provider (
ErrorResponse) được giữ nguyêncode/message/HTTP status khi ném exception ở phía gọi. - Cần gắn thêm organization context của người dùng hiện tại vào request liên service.
Cài đặt
Thêm dependency vào pom.xml — không khai version vì đã được quản lý tập trung qua BOM của Govex Cloud:
<dependency>
<groupId>vn.govex.cloud</groupId>
<artifactId>govex-cloud-feign</artifactId>
</dependency>
Nếu ứng dụng chưa dùng parent/BOM của Govex Cloud, xem hướng dẫn khai báo tại Cài đặt.
Cấu hình
Các bean được auto-configure khi có dependency trên classpath:
| Bean | Mô tả |
|---|---|
feign.Logger.Level | Mặc định BASIC — log request/response của provider. |
ErrorDecoder | FeignErrorDecoder, chỉ tạo khi context chưa có bean ErrorDecoder — có thể override bằng bean tự khai báo. |
Cấu hình client (timeout, logger level...) dùng theo chuẩn Spring Cloud OpenFeign:
| Property | Mô tả | Mặc định |
|---|---|---|
spring.cloud.openfeign.client.config.<contextId>.connect-timeout | Timeout kết nối (ms) tới provider. | Theo chuẩn Spring Cloud |
spring.cloud.openfeign.client.config.<contextId>.read-timeout | Timeout đọc response (ms). | Theo chuẩn Spring Cloud |
spring.cloud.openfeign.client.config.<contextId>.logger-level | Mức log Feign cho từng client (NONE, BASIC, HEADERS, FULL). | BASIC do dependency đặt |
Sử dụng
Bật Feign client cho ứng dụng (dependency không tự bật thay ứng dụng):
@EnableFeignClients
@SpringBootApplication
public class OrderApplication {
}
Khai báo client bằng @AuthorizedFeignClient — mặc định annotation đã dùng custom configuration có interceptor chuyển tiếp token:
@AuthorizedFeignClient(name = "iam-service", url = "${govex.services.iam-url}")
public interface IamClient {
@GetMapping("/api/v1/users/{id}")
ResultMessage<UserDTO> getUser(@PathVariable("id") String id);
}
Annotation hỗ trợ các alias tương đương @FeignClient: name, contextId, configuration, url, decode404, fallback, path. Chỉ truyền configuration khi muốn thay bộ interceptor mặc định.
Interceptor chỉ gắn Authorization khi request hiện tại có header này, và chỉ gắn organization context khi lấy được orgId của người dùng hiện tại. Vì vậy lời gọi từ luồng đã xác thực sẽ mang đủ ngữ cảnh; lời gọi nền (scheduler, job) không có token nên cần xử lý xác thực riêng nếu provider yêu cầu.
Muốn xử lý lỗi theo cách riêng, khai báo bean thay thế — auto-configuration sẽ nhường quyền:
@Bean
public ErrorDecoder errorDecoder() {
return new MyFeignErrorDecoder();
}
Lưu ý
- Cần có
govex-cloud-securityvàgovex-cloud-errortrong ứng dụng host: hai dependency này được khai báo ở scopeprovided, không tự mang theo. - Lỗi từ provider nên trả body theo cấu trúc
ErrorResponse; nếu body không parse được, client nhận lỗiINTERNAL_SERVER_ERRORthay vì mã lỗi nghiệp vụ. - Không đưa class
OAuth2InterceptedFeignConfigurationvào component scan toàn cục của ứng dụng — nó cố ý không có@Configurationđể tránh áp interceptor cho mọi Feign client ngoài ý muốn.