Spring feign

Jongmyung Choi·2023년 7월 13일
3
post-thumbnail

Feign?

Netflix에서 최초로 개발된 선언적 HttpClient 도구

Interface와 Annotation을 이용하여 Http API 클라이언트를 단순화 한다. RestTemplate 을 이용하여 API 호출을 하다가 Feign을 한번 써보면 얼마나 간단한지 알 수 있다.
오늘 처음 Feign을 보셨다면 앞으로 Feign만 쓰실겁니다

Feign 시작하기

1. 의존성 설정

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 에서 자세한 버전별 호환을 확인 할 수 있습니다.

2. @EnableFeignClients 추가

메인 어플리케이션 클래스에 @EnableFeignClients 어노테이션을 추가한다.

일반적으로 메인에 어노테이션을 추가하며, 하위 클래스에서 OpenFeign 관련 컴포넌트들을 스캔한다. ( @FeignClient 를 찾아서 구현체 생성)

@SpringBootApplication
@EnableFeignClients // !!!!!  
  public class FeignApplication {

      public static void main(String[] args) {
          SpringApplication.run(FeignApplication.class, args);

      }
  }

3. @FeignClient 인터페이스 구현

@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 넣기

//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");
    }
}

3.2 Auth 인증하기

//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");
    }
}

4. 사용하기

외부 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으로 구현 하였을 때랑 비교하면 확실히 코드의 축소가 많이 일어났고 가독성이 좋아졌다.
FeignController와 비슷한 모양을 가지고 있고 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/

profile
총명한 개발자

0개의 댓글