Netflix에서 최초로 개발된 선언적 HttpClient 도구
Interface와 Annotation을 이용하여 Http API 클라이언트를 단순화 한다. RestTemplate
을 이용하여 API 호출을 하다가 Feign
을 한번 써보면 얼마나 간단한지 알 수 있다.
오늘 처음 Feign을 보셨다면 앞으로 Feign만 쓰실겁니다
build.gradle
// 참고 : spring 3.0.8 버전 사용중
dependencies {
.
.
implementation platform("org.springframework.cloud:spring-cloud-dependencies:2022.0.1")
implementation "org.springframework.cloud:spring-cloud-starter-openfeign"
.
.
}
Spring cloud 의 Release Trains 에서 자세한 버전별 호환을 확인 할 수 있습니다.
메인 어플리케이션 클래스에 @EnableFeignClients 어노테이션을 추가한다.
일반적으로 메인에 어노테이션을 추가하며, 하위 클래스에서 OpenFeign 관련 컴포넌트들을 스캔한다. ( @FeignClient 를 찾아서 구현체 생성)
@SpringBootApplication
@EnableFeignClients // !!!!!
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
}
}
@FeignClient(name ="bean 이름" , url="호출할 api url", configuration = "설정 class")
// 기본 호출
@FeignClient(name = "step1", url = "https://httpbin.org")
public interface Step1Client {
@GetMapping("/status/{status}")
void status(@PathVariable("status") int status);
}
}
//header 를 넣어서 호출 하기
@FeignClient(name = "step2", url = "https://httpbin.org", configuration = {HeaderConfiguration.class})
public interface Step2Client {
@GetMapping(value = "/status/{status}")
void status(@PathVariable("status") int status);
@GetMapping(value = "/status/{status}", headers = "key2=value2")
void status2(@PathVariable("status") int status);
@GetMapping(value = "/status/{status}")
void status3(@RequestHeader("key3") String headers, @PathVariable("status") int status);
}
public class HeaderConfiguration {
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> requestTemplate.header("header", "header1", "header2");
}
}
//Basic Auth 인증 호출 하기
@FeignClient(name = "step3", url = "https://httpbin.org", configuration = {BasicAuthConfiguration.class})
public interface Step3Client {
@GetMapping("/status/{status}")
void status(@PathVariable("status") int status);
}
public class BasicAuthConfiguration {
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("mayaul", "1234567890");
}
}
외부 api 호출을 통해서 테스트를 진행해보자
무료 API 의 유저를 조회하는 url을 호출하였다.
호출 인터페이스 구현
@FeignClient(name = "userClient", url = "https://randomuser.me")
public interface UserClient {
@GetMapping(value = "/api/")
GetUsersResponse getUsers(@RequestParam("nat") String nation);
}
Response Dto
Getter
@AllArgsConstructor
@NoArgsConstructor
public class GetUsersResponse {
private List<Result> results;
@Getter
@AllArgsConstructor
@NoArgsConstructor
public static class Result {
private String gender;
private String email;
}
}
결과
위 코드를 똑같이 RestTemplate
으로 구현 하였을 때랑 비교하면 확실히 코드의 축소가 많이 일어났고 가독성이 좋아졌다.
Feign
은 Controller
와 비슷한 모양을 가지고 있고 JPA
를 사용할때 처럼 간편하게 어노테이션 만으로 구현체를 만들어준다.
뿐만 아니라 부하 분산, 오류처리 도 세련되게 도와주기 때문에 실무에서는 Feign
을 사용한다고 한다.
https://techblog.woowahan.com/2630/
https://github.com/woowabros/feign-apply-experience-sample
https://isntyet.github.io/java/feign-client-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0/