Chuyển tới nội dung chính

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 Authorization token của người dùng hiện tại sang service đích thay vì tự viết RequestInterceptor.
  • Muốn lỗi nghiệp vụ từ provider (ErrorResponse) được giữ nguyên code/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:

BeanMô tả
feign.Logger.LevelMặc định BASIC — log request/response của provider.
ErrorDecoderFeignErrorDecoder, 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:

PropertyMô tảMặc định
spring.cloud.openfeign.client.config.<contextId>.connect-timeoutTimeout kết nối (ms) tới provider.Theo chuẩn Spring Cloud
spring.cloud.openfeign.client.config.<contextId>.read-timeoutTimeout đọc response (ms).Theo chuẩn Spring Cloud
spring.cloud.openfeign.client.config.<contextId>.logger-levelMứ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-securitygovex-cloud-error trong ứng dụng host: hai dependency này được khai báo ở scope provided, 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ỗi INTERNAL_SERVER_ERROR thay vì mã lỗi nghiệp vụ.
  • Không đưa class OAuth2InterceptedFeignConfiguration và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.