ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • FeignClient
    BackEnd/MSA Communications 2022. 7. 23. 07:22
    반응형

    Overview

      해당 글에서는 RestTemplate보다 사용이 간단하고 직관적인 FeignClient를 적용해 보겠습니다. FeignClient는 HTTP Client로 REST Call을 추상화 한 Spring Cloud Netflix 라이브러리입니다.

     

    FeignClient 적용

    의존성 추가

    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'

    @EnableFeignClients 적용

    package com.example.userservice;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class UserServiceApplication {
    
      public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
      }
    
      @Bean
      public RestTemplate getRestTemplate() {
        return new RestTemplate();
      }
    }

    호출하려는 HTTP Endpoint에 대한 Interface 생성 (url은 config 파일로 관리합니다.)

    package com.example.userservice.client;
    
    import com.example.userservice.RestTemplateResponse;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    @FeignClient(name = "jsonPlaceHolderClient", url = "https://jsonplaceholder.typicode.com/")
    public interface JsonPlaceHolderClient {
    
      @GetMapping("/todos/{id}")
      RestTemplateResponse getTodos(@PathVariable String id);
    }

    FeignClient 사용

      JsonPlaceHolderClient를 생성자 주입 받아 getTodos 메서드를 호출합니다. 단순 확인을 위한 호출로 Controller 단에서 수행하며, 이전 글의 RestTemplateResponse를 그대로 적용합니다. 

    package com.example.userservice;
    
    import com.example.userservice.client.JsonPlaceHolderClient;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.core.env.Environment;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    @RequestMapping("/")
    public class UserController {
      /*** 생략 ***/
    
      JsonPlaceHolderClient jsonPlaceHolderClient;
    
      @Autowired
      public UserController(Environment env, RestTemplate restTemplate,
          JsonPlaceHolderClient jsonPlaceHolderClient) {
      	/*** 생략 ***/
        this.jsonPlaceHolderClient = jsonPlaceHolderClient;
      }
    
      @GetMapping("/welcome")
      public String welcome() {
        String configMessage = env.getProperty("greeting.message");
    
        /* RestTemplate */
    //    System.out.println(restTemplate.getForObject("https://jsonplaceholder.typicode.com/todos/1",
    //        RestTemplateResponse.class));
    //    restTemplate.getForObject("url", Object.class);
    //    restTemplate.postForObject("url", "Request.class", Object.class);
    //    restTemplate.put("url", "Request.class");
    //    restTemplate.delete("url");
    
        /* FeignClient */
        RestTemplateResponse response = jsonPlaceHolderClient.getTodos("1");
        System.out.println(response);
    
        return "Hello, User-service: " + configMessage;
      }
    }

     

    FeignClient Logger

    application.yml (com.example.userservice.client는 package 경로입니다.)

    logging:
      level:
        com.example.userservice.client: DEBUG

    @Bean 등록

    package com.example.userservice;
    
    import feign.Logger;
    /*** 생략 ***/
    
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class UserServiceApplication {
      /*** 생략 ***/
    
      @Bean
      public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
      }
    }

    서버 재기동 후 호출 시 아래와 같은 로그를 볼 수 있습니다.

     

    FeignClient Exception 처리

    ErrorDecoder 구현

      FeignClient에서 발생하는 Exception을 한 곳에서 처리할 수 있습니다. @Component로 @Bean을 등록하고 ErrorDecoder를 상속받아 decode 메서드를 재정의하면 됩니다. 상태코드에 따라 적절한 처리를 해주면 됩니다.

    package com.example.userservice.client;
    
    import feign.Response;
    import feign.codec.ErrorDecoder;
    import org.springframework.http.HttpStatus;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ResponseStatusException;
    
    @Component
    public class FeignErrorDecoder implements ErrorDecoder {
    
      @Override
      public Exception decode(String methodKey, Response response) {
        switch (response.status()) {
          case 400:
            break;
          case 404:
            if (methodKey.contains("getTodos")) {
              return new ResponseStatusException(HttpStatus.valueOf(response.status()),
                  "getTodos Bad Request Exception!!!");
            }
            break;
          default:
            return new Exception(response.reason());
        }
    
        return null;
      }
    }

     

     

     

    [참고 정보]

    반응형

    'BackEnd > MSA Communications' 카테고리의 다른 글

    RestTemplate  (0) 2022.07.20

    댓글

Designed by Tistory.