Search

SpringBoot FeignClient 도입기

Created time
2024/05/02 15:35
Tags
SpringBoot
프로젝트

FeignClient란?

feign
OpenFeign
Netflix에서 시작된 HTTP client binder로서, Spring Cloud 프로젝트의 일부로 개발되었다고 소개됩니다. Java Interface 기반으로 동작하며, Interface에 Http client 관련 코드를 선언적으로 정의하여 RESTful 서비스에 대한 요청을 처리할 수 있습니다.
RESTful 서비스에 관련한 HTTP 요청을 작성 및 호출할 때 많은 보일러 플레이트 코드를 줄인다는 점에서 기존의 RestTemplate 기반 HTTP 요청 코드에 비해 상당한 장점을 가집니다.
예를 들어 카카오 OAuth 로그인을 구현한다고 가정했을 때, RestTemplate 기반으로 작성된 코드는 다음과 비슷한 형태를 가집니다.
WebClient kakaoApiWebClient = WebClient.builder() .baseUrl(kakaoApiUrl) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .build(); Map<String, Object> kakaoResponse = kakaoApiWebClient .post() .uri(uriBuilder -> uriBuilder .path("/v2/user/me") .build()) .header("Authorization", "Bearer " + accessToken) .retrieve() .bodyToMono(Map.class) .block(); Map<String, Object> kakaoAccountMap = (Map<String, Object>) kakaoResponse.get("kakao_account"); Map<String, String> profileMap = (Map<String, String>) kakaoAccountMap.get("profile");
Java
복사
하지만 FeignClient 를 사용한다면 다음과 같은 형태로 훨씬 간결하게 사용할 수 있습니다.
@FeignClient(name = "kakaoOAuthFeignClient", url = {oauth2.kakao.baseurl", configuration = KakaoClientConfiguration.class) @Component public interface KakaoOAuthFeignClient { @PostMapping(value = "/oauth/token") KakaoLoginRes getKakaoOAuthToken(@RequestBody String accessToken); }
Java
복사
또한 Spring Cloud 프로젝트의 일부로서 개발되었기 때문에, Ribbon 과 함께 로드 밸런싱 기능을 제공하고, Eureka 와 함께 MSA에서 서버 간 네트워크 통신을 관리하는 역할을 하기도 합니다.

서버에서 FeignClient를 도입하게 된 배경

현재 서버의 Multi-module 프로젝트는 위와 같은 형태로 레이어드 아키텍처별 기능을 응집 및 분리한 Api, Domain, Storage 모듈과, 공통적으로 사용하는 Enum 등을 관리하는 Common 모듈, 외부와의 연결을 담당하는 InfraStructure 모듈로 구성되어 있습니다.
FeignClientInfrastructure 모듈에서 implementation 하여 필요 기능을 구현하는 데 사용됩니다.
리그 오브 레전드 패치노트 구독 웹서비스는 1. 이메일 기능, 2. riot api 연동 기능 등 외부 API 혹은 RESTful API와 통신해야 할 일이 잦습니다. 만약 위의 예시처럼 RestTemplate 만을 사용해서 외부와 통신한다면 지나치게 기능 별로 하나 하나 코드를 구현하게 될 가능성이 높고, 무엇보다 생산성이나 확장성 면에서도 필요한 자원이 너무 많아집니다.
따라서 다양한 외부 클라이언트와의 현재 연결 및 추가적인 연결을 고려하여 FeignClient 도입을 고려하게 되었습니다.