티스토리 뷰

반응형

서론

기존 다른 서버들과 통신하는 Rest API를 사용할 때에 RestTemplate을 사용해서 데이터를 가져왔습니다.

https://dolgogae.tistory.com/42

 

[API] 3. Spring Boot - Naver API 호출(GET)

해당 글의 소스코드는 링크 걸어 두었습니다. GitHub - dolgogae/TIL: Today I Learned Today I Learned. Contribute to dolgogae/TIL development by creating an account on GitHub. github.com 앞선 Get, Post를 통해서 Naver API를 호출해보

dolgogae.tistory.com

 

위의 저의 글처럼 RestTemplate을 사용해서 API 호출을 했고

위 포스팅에서는 코드의 중복을 줄이기 위해서 제네릭한 코드를 사용했습니다.

하지만 Feign Client를 사용하게 되면 앞선 방법보다 더 쉽게 간결한 API 호출이 가능해집니다.

기존에 Spring을 써오면서 어노테이션과 인터페이스를 활용해서(예: Spring Data JPA) 편리하게 코딩을 하듯

API 호출 또한 편리하게 관리 할 수 있고 로깅에 대한 부분도 편하게 할 수 있습니다.

 

Feign Client란?

Feign Client는 MSA에서 서비스간 HTTP 통신을

간단하고 간결하게 만들어주는 선언적 웹 서비스 클라이언트입니다.

Spring Cloud와 함께 사용되며, 인터페이스 기반의 어노테이션을 통해 서비스를 손쉽게 호출할 수 있게 해줍니다.

OOP의 목적처럼 개발자는 HTTP 클라이언트의 복잡성을 신경 쓰지 않고,

서비스간 통신을 쉽게 구현할 수 있도록 하는것 입니다.

 

Feign Client 사용

우선 가장 먼저 해줘야 할 것은 어느 라이브러리나 동일하게 dependency 설정입니다.

Gradle

implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '4.1.0'

Maven

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>4.1.0</version>
</dependency>

 

이후 main 함수에 @EnableFeignClients를 붙여줍니다.

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

 

그리고 호출해줄 API에 대한 정보를 위해 interface를 만들어줍니다.

저의 경우에는 NaverFeignClient라는 interface를 만들었고 위 포스팅과 같은 Naver API를 호출하도록 하겠습니다.

@FeignClient(
        name = "naver-client",
        url = "${feign.url.prefix}",
        configuration = CustomFeignConfig.class
)
public interface NaverFeignClient {

    @GetMapping("/v1/search/local.json")
    ResponseEntity<SearchLocalRes> callNaverLocal(@RequestHeader("X-Naver-Client-Id") String id,
                                             @RequestHeader("X-Naver-Client-Secret") String passwd,
                                             @RequestParam("query") String query,
                                             @RequestParam("display") int display,
                                             @RequestParam("start") int start,
                                             @RequestParam("sort") String sort
}

 

Naver API 호출에 대한 자세한 내용은 위에 첨부해둔 곳에 설명이 있으니 생략을 하겠습니다.
SearchLocalRes(DTO)도 위 포스팅에서 확인 가능합니다.

 

위처럼 @FeignClient 어노테이션에 몇가지 설정 값들을 넣어줍니다.

name은 현재 Feign Client를 식별해주는 이름을 지정하는 설정값이고 url은 호출할 URL 주소입니다.

이 URL 주소는 프로퍼티로 관리해주는 것이 좋습니다.

feign:
  url:
    prefix: https://openapi.naver.com
  client:
    config:
      default:
        connectTimeout: 1000
        readTimeout: 3000
        loggerLevel: NONE
      naver-client: 
        connectTimeout: 1000
        readTimeout: 10000
        loggerLevel: HEADERS

configuration은 현재 이 interface에서 참고할 Config 설정들(지엽적인 설정)이 있는 Class 입니다. 

configuration 같은 경우에는 이후에 설명하겠지만 interceptorerror decoder등에 대한 설정이 들어갑니다.

 

더 자세하게 선언한 메서드를 살펴보면

@GetMapping("/v1/search/local.json")
ResponseEntity<SearchLocalRes> callNaverLocal(@RequestHeader("X-Naver-Client-Id") String id,
                                         @RequestHeader("X-Naver-Client-Secret") String passwd,
                                         @RequestParam("query") String query,
                                         @RequestParam("display") int display,
                                         @RequestParam("start") int start,
                                         @RequestParam("sort") String sort

 

그리고 GetMapping을 통해서 Get Method의 API를 호출하도록 하고 호출할 주소를 적어줍니다.

마지막으로 method의 인자를 통해서 Get Method의 파라미터와 필수, 필요 Header들을 넣어주면 됩니다.

 

post method도 비슷한 방법으로 호출이 가능합니다.

@PostMapping("/v1/datalab/search")
ResponseEntity<DatalabTotalSearchResponse> callNaverDatalab(@RequestHeader("X-Naver-Client-Id") String id,
                                         @RequestHeader("X-Naver-Client-Secret") String passwd,
                                         @RequestBody DatalabTotalSearchRequest datalabTotalSearchRequest);

 

다음과 같이 RestTemplate을 사용할 때 보다 훨씬 간결한 호출이 가능해집니다.

 

Feign Client 자세히 살펴보기

Feign Client를 조금 더 자세하게 살펴보면 우선 @FeignClient는 다음과 같은 설정 값들이 있습니다.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FeignClient {
    @AliasFor("name")
    String value() default "";

    String contextId() default "";

    @AliasFor("value")
    String name() default "";

    String[] qualifiers() default {};

    String url() default "";

    boolean dismiss404() default false;

    Class<?>[] configuration() default {};

    Class<?> fallback() default void.class;

    Class<?> fallbackFactory() default void.class;

    String path() default "";

    boolean primary() default true;
}

 

위 소스코드에서도 Feign Client의 설정들을 살펴 볼 수 있고

Feign Client Docs에서 default 설정들을 살펴 볼 수 있습니다.

 

https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#spring-cloud-feign-overriding-defaults

 

Spring Cloud OpenFeign

Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable

docs.spring.io

 

 

위에서 눈에 띄는 값들은 CachingCapabilityClient가 있습니다.

설명에도 나와 있듯 CachingCapability는 Feign Client에서 @Caching을 사용할 수 있도록 만든 것이고Client는 어떤 HTTP Client를 가져다 쓸지 정할 수 있는 설정 값입니다. 

 

두 설정은 다른 설정들과 다르게 외부 설정파일(application~)에서 설정이 가능합니다. CachingCapability은 Caching의 개념을 안다면 쉽게 이해가 가능하니 넘어가도록 하고 Client 에 대해서 조금 더 자세히 살펴보고자 합니다.

 

 

 

OpenFeign Docs에서는 다음과 같이 Client에 대해서 자세하게 설명이 되어 있습니다.Feign Client도 HTTP Client를 쉽게 사용하는 것이 목적인 만큼 그 Client를 내 프로젝트에 맞게 골라주는 것 또한 중요하다고 생각합니다.

 

위 문서의 예시로 Apache HttpClient 5를 사용하고 싶다면

spring:
  cloud:
    openfeign:
      httpclient:
        hc5:
          enabled: true

 

위와 같이 설정이 가능하다. 그리고 기본 값으로는 FeignBlockingLoadBalancerClient 를 사용하고,

사용 설정값들을 확인하려면

FeignAutoConfiguration(org.springframework.cloud.openfeign)에서 확인이 가능합니다.

 

위에서 예시로 들었던 Apache HttpClient 5쪽의 소스코드를 확인해보면 다음과 같습니다.

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({ApacheHttp5Client.class})
@ConditionalOnMissingBean({CloseableHttpClient.class})
@ConditionalOnProperty(
    value = {"spring.cloud.openfeign.httpclient.hc5.enabled"},
    havingValue = "true",
    matchIfMissing = true
)
@Import({org.springframework.cloud.openfeign.clientconfig.HttpClient5FeignConfiguration.class})
protected static class HttpClient5FeignConfiguration {
    protected HttpClient5FeignConfiguration() {
    }

    @Bean
    @ConditionalOnMissingBean({Client.class})
    public Client feignClient(CloseableHttpClient httpClient5) {
        return new ApacheHttp5Client(httpClient5);
    }
}

 

이렇게 설정하는 코드를 확인 할 수 있고 FeignAutoConfiguration에서 다른 설정들도 확인이 가능합니다.

이를 통해서 나의 프로젝트에 맞게 적합한 HTTP Client를 고려하여 설정하는 것이 중요하다고 생각합니다.

 

이번 포스팅에서는 Feign Client의 개념과 사용법 그리고 조금 더 심화된 내용에 대해서 알아봤습니다.

다음 포스팅에서는  interceptor나 error decoder등의 설정을 다루도록 하겠습니다.

728x90
반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함
250x250