MSA 서비스간 통신시 RestTemplate vs FeignClient

CHOI YUN HO·2022년 9월 22일
2

SW Maestro

목록 보기
12/13
post-thumbnail

왜 이 기술을 사용해야 하는가에 대한 고민

현재 SW 마에스트로 메인 프로젝트를 진행하면서, 가장 많이 느끼는 것 중에 하나는
프로젝트의 완성도 중요하지만...그 과정에서 어떤 기술을 사용할지 그리고 왜 그 기술을 선택했는지에 대한 근거를 충분히 고민하며 진행해야겠다는 것이다.

따라서 현재 MSA로 이루어져있는 서버에서 서비스간 통신을 위한 기술들에 대해 좀 더 자세히 알아보고 무엇이 적합할지 고민하는 시간을 가져본다.

RestTemplate


RestTemplate이란?

REST API를 호출할 수 있는 Spring 내장 클래스이다.
Spring 3.0부터 지원되었고, json, xml 응답을 모두 받을 수 있다.
REST API 서비스를 요청 후 응답 받을 수 있도록 설계되어있으며 HTTP 프로토콜의 메소드(ex. GET, POST, DELETE, PUT)들에 적합한 여러 메소드들을 제공한다.

  • Spring Framework 5부터는 WebFlux 스택과 함께 Spring은 WebClient 라는 새로운 HTTP 클라이언트를 도입하여 기존의 동기식 API를 제공할 뿐 만 아니라 효율적인 비차단 및 비동기 접근 방식을 지원하여, Spring 5.0 이후 부터는 RestTemplate는 deprecated 되었다.

RestTemplate의 특징

  • Spring 3.0 부터 지원하는 Spring의 HTTP 통신 템플릿
  • HTTP 요청 후 JSON, XML, String 과 같은 응답을 받을 수 있는 템플릿
  • 멀티 스레드 방식을 사용
  • Blocking I/O 기반의 동기방식을 사용하는 템플릿
  • RESTful 형식에 맞추어진 템플릿
  • Header, Content-Tpye등을 설정하여 외부 API 호출
  • Server to Server 통신에 사용

FeignClient


FeignClient란?

Feign 은 Netflix 에서 개발된 Http client binder 이다.

FeignClient의 특징

  • Feign 을 사용하면 웹 서비스 클라이언트를 보다 쉽게 작성할 수 있다.
  • Feign 을 사용하기 위해서는 interface 를 작성하고 annotation 을 선언 하기만 하면된다.(Spring Data JPA 에서 실제 쿼리를 작성하지 않고 Interface 만 지정하여 쿼리실행 구현체를 자동으로 만들어주는 것처럼)

RestTemplate vs Feign 비교


관심사의 분리

두 방식 모두 요청 URI를 직접 명시해줘야 한다.
하지만 다른 점이 있다면 관심사의 분리이다.

예를 들어 리뷰 MS의 ReviewService 계층의 행동에 대한 관심사는 유저 MS의 API를 호출하는 것(요청을 보내는 것)으로 Feign이나 RestTemplate이나 동일하다.

하지만 호출을 위한 설정 정보를 ReviewService가 가지는게 맞을까? 생각해볼 필요가 있다.

책임의 관심사로 봤을 때, 유저 MS의 API URI가 달라진다면 그에 대한 책임은 ReviewService가 아니라 API를 호출하는 로직 자체에 존재한다. 하지만 RestTemplate은 설정 정보가 ReviewService내에 직접적으로 존재하기 때문에 ReviewService가 책임을 지고 있다.

그에 반해 Feign은 설정 정보가 FeignClien 인터페이스에 존재하기 때문에 관심사가 분리되어 있다. 결국 이를 가져다 쓰는 ReviewService에서는 반환에 대한 결과만을 책임으로 갖고 있다.

이런 측면에서 Feign이 더 좋다고 생각하며 추가적으로 코드의 양이나 직관성 측면에서도 장점을 가지고 있는것 같다.

(다만 나는 현재 혼자서 모든 MS를 개발하고 있지만 그게 아니라 각 서비스를 다른 사람이나 팀에서 개발한다면 오히려 직관적이지 못할 수도 있겠다는 생각이 들기도 했다.. 인터페이스 내에서 다른 애플리케이션의 메소드를 호출하는 형식이기 때문에 RestTemplate에 비해 명확한 구조를 파악하는데 어려울 수 있지 않을까?)

예외 처리

예를 들어 리뷰 MS에서 유저 MS에 존재하지 않는 유저에 대한 요청을 보낸다면, 500에러가 발생한다.
유저 MS에서는 유저를 찾을 수 없기 때문에 잘못된 리소스에 대해 404가 발생하지만.. 리뷰 MS 입장에서는 요청에 대한 응답을 받지 못하여 결과를 처리할 수 없으므로 500에러가 발생한다.

하지만 이런 상황에서 리뷰 MS는 500이 아닌 404를 반환해야 한다.

이럴 때
RestTemplate은 try-catch를 이용하여 예외를 처리해줘야 한다.
Feign은 예외를 핸들링하기 위한 ErrorDecoder를 제공한다.

테스트 용이성

단위 테스트를 할 때는 외부 모듈과의 의존 관계를 끊는 것이 중요하다.
말 그대로 해당 모듈에 대한 "단위" 테스트를 진행해야하기 때문이다.

따라서 Unit을 테스트하기 위해서 보통 의존 관계를 끊고 mock 객체를 stubbing 하여 테스트한다.
그럼 UserService 에서 RestTemplate 을 주입받게 된다면 RestTemplate 의 exchange 는 어떻게 stubbing 해야할까?

RestTemplate 이 호출하는 URL이 늘어나면 그럼 RestTemplateBuilder 를 이용해서 하나 하나 매핑을 해줘야한다.

현재 Eureka 를 이용해서 API 호출 Endpoint 를 MSA 인스턴스 이름으로 지정했는데, 테스트 코드에서는 일일이 모두 적어줘야 하고, 만약 URI가 변경된다면 이와 관련된 모든 API 를 호출하는 테스트를 변경해야 한다.

그에 반해 Feign 은 인터페이스의 반환 객체만 매핑해준다는 점에서 아주 매력적이다.

참고 및 출처

https://happycloud-lee.tistory.com/220
https://tecoble.techcourse.co.kr/post/2021-07-25-resttemplate-webclient/
https://wonit.tistory.com/507

profile
가재같은 사람

1개의 댓글

comment-user-thumbnail
2023년 2월 12일

너무 잘 보고 갑니다. 이해하기 쉽게 설명해 주셔서 감사합니다!!

답글 달기