OpenFeign은 Spring Cloud 기반의 선언적 HTTP 클라이언트 도구로, 간편하게 외부 API를 호출 할 수 있는 도구이다.
어노테이션과 인터페이스 기반의 간소화된 코드 작성으로, 외부 API를 마치 로컬 메서드처럼 호출해서 사용할 수 있다.
(Spring Data JPA에서 인터페이스를 통해 DB 처리 메서드를 작성하는 것과 유사하다.)
OpenFeign의 장점
- 인터페이스와 어노테이션 기반이므로, 이전 방식(RestTemplate 등)에 비해 작성할 코드를 줄일 수 있음
- Spring MVC Annotation(@GetMapping, @RequestBody…)를 활용해 구성 가능
- Spring Cloud의 다른 기술들( Eureka, Ribbon, Hystrix 등 )과 통합이 용이
시작하기
OepnFeign은 Spring Cloud 기반 기술로 주로 Spring Cloud 환경에서 사용되지만, 기존 방식의 Spring Boot 프로젝트에서도 활용이 가능하다.
// Gradle
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:{version}'
(사용 중인 Spring Boot 버전에 맞게 OpenFeign의 버전을 명시해야 하는데, 아래 이미지와 링크를 참고)
의존성을 추가했다면, 메인 클래스 또는 Configuration 클래스에 @EnableFeignClients 어노테이션을 추가한다.
@ComponentScan 이 스프링 컴포넌트를 스캔해 Bean으로 등록하는 것과 유사하게, @EnableFeignClients 는 Feign 클라이언트를 스캔하고 등록하는 기능을 한다.
(※ Configuration 클래스에 @EnableFeignClients 어노테이션을 추가하는 경우, basePackages를 명시해줘야 함!)
// 메인 클래스에 추가하는 경우
@EnableFeignClients
@SpringBootApplication
public class FooApplication {
public static void main(String[] args) {
SpringApplication.run(FooApplication.class, args);
logServerStart();
}
}
// Configuration 클래스에 추가하는 경우
@Configuration
@EnableFeignClients(basePackages = "com.example.demo")
public class FeignConfig {
// 이 클래스 내에서 정의된 Bean과 설정은 모든 Feign Client에 적용된다.
}
설정하기
Feign Client의 동작을 제어하거나, 커스터마이징하려는 경우, Configuration 클래스를 정의할 수 있다.
- 로깅 레벨 정의
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL; // 옵션 : NONE, BASIC, HEADERS, FULL
}
NONE < BASIC < HEADERS < FULL 순으로 자세한 정보를 로깅한다.
- NONE : 아무 정보도 로깅하지 않음
- BASIC : 요청 메서드와 URL, 응답의 상태 코드 및 요청 처리 시간
- HEADERS : BASIC에 더해 요청과 응답의 헤더 정보
- FULL : BASIC과 HEADERS의 모든 정보와 모든 메타데이터
- 재시도 정책
@Bean
public Retryer retryer() {
// Parameter : (long period, long maxPeriod, int maxAttempts)
return new Retryer.Default(10L, 1L, 5);
}
- period : 재시도 간의 대기 시간 / default : 100밀리초
- maxPeriod : 재시도 간의 최대 대기 시간 / default : 1초
- maxAttempts : 최대 재시도 횟수 / default : 5회
- 에러 처리 정책
@Bean
public ErrorDecoder errorDecoder() {
return new YourErrorDecorder();
}
ErrorDecoder의 decode 메서드를 오버라이드해 내가 사용할 에러 처리 정책을 정의하면 된다.
public class YourErrorDecorder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
// Handling Logic
}
}
- 요청 옵션 정의
@Bean
public Request.Options options() {
// Options(Duration connectTimeout, Duration readTimeout, boolean followRedirects)
return new Request.Options(Duration.ofSeconds(10), Duration.ofSeconds(60), true);
}
- connectTimeout : 연결을 시도하는 최대 시간 / default : 10초
- readTimeout : 응답을 기다리는 최대 시간 / default : 60초
- followRedirects : HTTP 리디렉션을 자동으로 따를지 여부 / default : true
(※ 밀리초 단위로 Timeout을 설정하던 방식은 Deprecated되었으니, Duration 형식으로 입력해야 함! )
- 인터셉터 정의
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate
-> requestTemplate
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + yourToken)
// Custom Header
.header("Custom-Header", "CustomValue")
// Query Parameter
.query("param1", "value1")
.query("param2", "value2");
}
Feign Client가 HTTP 요청에 공통으로 사용할 옵션을 RequestInterceptor를 통해 설정할 수 있다.
사용하기
@FeignClient(name = "FeignExample", url = "https://api.example.com/v1")
public interface UpbitFeignClient {
@GetMapping("/user/{userId}")
String getUserInfo(@PathVariable("userId") int userId);
// Other API Endpoint
}
@FeignClient 어노테이션으로 이 인터페이스가 Feign Client임을 선언한고, url 속성에 호출할 외부 서비스의 기본 URL을 작성한다.
name 속성으로 Feign Client의 이름을 지정하거나, configuration 클래스로 전역 설정 외의 설정을 추가로 적용할 수도 있다.
그 후, 인터페이스 내에 메서드를 선언해주면 되는데,
- 호출하려는 서비스가 GET 메서드, /ping 엔드포인트를 사용하고, 응답이 "pong"(String )이라면,
- @GetMapping("/ping") 으로 엔드포인트를 매핑한다.
- API의 응답에 맞게 반환 타입을 String으로 지정한다.
호출하려는 API가 파라미터를 요구하는 경우
Controller 단에서 HTTP 요청을 매핑하는 것과 유사하게, 메서드 시그니처를에 매핑하면 된다.
- @PathVariable : URL 경로 변수를 매핑할 때 / e.g. @PathVariable("id") int id
- @RequestParam : 쿼리 파라미터를 매핑할 때 / e.g. @RequestParam("value") String value
- @RequestBody : 요청 본문에 포함된 데이터를 객체로 매핑할 때 / e.g. @RequestBody RequestDto request
API의 응답이 본문을 포함하는 경우
API의 응답이 본문을 포함하는 경우, 해당 응답의 형식에 맞는 자바 객체(예: DTO 등)를 정의하여 응답 데이터를 매핑할 수 있다. Feign Client의 메서드 반환 타입을 DTO로 설정하 API 응답을 적절히 처리한다.
추가
JSONPlaceholder, Reqres와 같은 가짜 데이터를 제공하는 서비스를 사용하면 API 호출 구성이 올바르게 되었는지 빠르게 테스트하는 데 유용하다.
참고한 자료
'Framework > Spring' 카테고리의 다른 글
[Spring] 혼자서 해보는 가상화폐 시세 알림 API - 확장 (0) | 2024.01.17 |
---|---|
[Spring] 혼자서 해보는 가상화폐 시세 알림 API - 구현 (2) | 2024.01.14 |
[Spring] 혼자서 해보는 가상화폐 시세 알림 API - 설계 (0) | 2024.01.11 |
[Spring] 스프링 프레임워크 핵심 원리 (1) | 2023.11.27 |
[Spring Boot] 기능 기반 패키지 구조(package-by-feature) (0) | 2023.10.22 |