Fegin이란?
- Fegin은 Netflix에서 개발된 선언적인 HTTP Client 도구로서, 외부 API 호출을 쉽게할 수 있도록 도와준다.
- '선언적인' 이란 어노테이션 사용을 의미한다. Fegin은 인터페이스에 어노테이션들만 붙여주면 구현이 된다.
- 이러한 방식은 Spring Data JPA와 유사하며, 상당히 편리하게 개발할 수 있도록 도와준다.
- Spring Data JPA를 사용하는 것처럼,
추상화를 통해 구현체를 작성하지 않고 Interface만 작성하면 자동으로 구현된다.
- RestTemplate보다 훨씬 간결하다. (RestTemplate은 대체되고 있기 때문에 주의해서 사용해야 한다.
- 가장 큰 장점은 작성할 코드가 줄어든다는 것이다.
RestTemplate vs. Fegin
- 환율 조회 API를 RestTemplate으로 작성한 것
@Component
@RequiredArgsConstructor
class ExchangeRateRestTemplate {
private final RestTemplate restTemplate;
private final ExchangeRateProperties properties;
private static final String API_KEY = "apikey";
public ExchangeRateResponse call(final Currency source, final Currency target) {
return restTemplate.exchange(
createApiUri(source, target),
HttpMethod.GET,
new HttpEntity<>(createHttpHeaders()),
ExchangeRateResponse.class)
.getBody();
}
private String createApiUri(final Currency source, final Currency target) {
return UriComponentsBuilder.fromHttpUrl(properties.getUri())
.queryParam("source", source.name())
.queryParam("currencies", target.name())
.encode()
.toUriString();
}
private HttpHeaders createHttpHeaders() {
final HttpHeaders headers = new HttpHeaders();
headers.add(API_KEY, properties.getKey());
return headers;
}
}
출처: https://mangkyu.tistory.com/278 [MangKyu's Diary:티스토리]
- 요즘 같이 API 호출이 잦은 MSA의 시대에서 이런 코드를 반복한다는 것은 번거롭다..!
@FeignClient(name = "ExchangeRateOpenFeign", url = "${exchange.currency.api.uri}")
public interface ExchangeRateOpenFeign {
@GetMapping
ExchangeRateResponse call(
@RequestHeader String apiKey,
@RequestParam Currency source,
@RequestParam Currency currencies);
}
출처: https://mangkyu.tistory.com/278 [MangKyu's Diary:티스토리]
Fegin의 단점 및 한계
- HTTP Client가 HTTP2를 지원하지 않는다.
- 공식적으로 Reactive 모델을 지원하지 않는다.
- 경우에 따라서 애플리케이션이 뜰 때, 초기화 에러가 발생할 수 있다
- 테스트 도구를 제공하지 않는다.
[Feign 구현하기]
의존성 추가하기
- Fegin은 Spring Cloud 기반의 기술이므로, Spring Cloud에 대한 의존성이 필요하다. Spring Cloud 문서를 보면 현재의 Spring Boot 버전에 맞는 버전이 명시되어 있다.
https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2021.0-Release-Notes
- 필자는 Spring Boot 버전이 2.7.13이어서 Spring Cloud Netflix 버전을 3.1.7로 맞췄다.
ext {
set('springCloudVersion', "2021.0.4")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:3.1.7'
Main
@EnableFeignClients
@SpringBootApplication
public class FeignTest {
public static void main(String[] args) {
SpringApplication.run(FeignTest.class, args);
}
}
@EnableFeignClients
- @EnableFeignClients는 @SpringBootApplication 하위 경로에 선언한다.
- @EnableFeignClients는 하위 경로의 @FeignClient를 Scan한다.
public interface TestClient
@FeginClient(value = "test1", url = "http://localhost:8080")
public interface TestClient {
@GetMapping("/testget/get/{string}")
String testGetFeign(@PathVariable("string") String string);
}
@FeignClient
- value : FeignClient의 서비스 이름으로, 필수 속성이다. BeanName과는 다르다.
- url : 해당 interface의 baseUrl이다.
- Class 레벨에서 @RestMapping으로 Handler들을 묶어주는 것과 비슷하다.
- configuration : 관련 커스터마이징 Configuration을 설정할 수 있다.
- qualifier : 추가 구분자를 설정해준다.
- fallback : Hystrix fallback 메서드이다.