본문 바로가기
[Spring]/Spring 기본

Spring Boot에서 외부 API 서버와 통신하는 기술에 대해 알아보자

by 황원용 2023. 8. 27.
728x90
 💡
 프로젝트에서 클라이언트로부터 받은 요청을 다른 API 서버에 전달하고 데이터를 받아 로직 처리 후 응답하는 기능이 필요했다. 지금까지 만들어 본 서버는 3-tier architecture라고 불리는 클라이언트 - 서버 - 데이터베이스 서버 간 통신의 범주에 크게 벗어나지 않았기 때문에 요청을 받아 다른 서버로 다시 넘겨주려면 어떻게 해야 하는지 감이 잡히지 않았다. GPT와 블로그 검색을 통해 찾아보니 정말 많은 방법이 있었다. 그중 5가지 방법을 추려내어 정리하려고 한다. 

 

 

📌 여러 가지 방법과 장단점

 Spring Boot를 사용하여 외부 API 서버와 통신하는 다양한 방법 중 RestTemplate, Spring WebClient, Spring Cloud OpenFeign, OkHttp, HttpClient에 대해 각각 장단점을 비교하고 최종적으로 무엇을 선택할 것인지에 대해 이야기해보겠다.

 

 

RestTemplate

  • RestTemplate은 Spring 3.0부터 제공되어 왔던 동기식 HTTP 클라이언트로, RESTful 서비스를 호출할 때 많이 사용된다.

🙂 장점

  • 사용하기 쉽고 코드가 직관적이다.
  • HTTP 메서드(GET, POST 등)에 대한 다양한 메서드를 제공한다.

🙃 단점

  • 2020년 이후로 deprecated 되었으며 대신 WebClient를 사용하는 것이 권장되고 있다.
    • 여기서 deprecated 되었다는 표현은 곧 제거될 것이라는 의미보다는 더 이상 큰 업데이트가 이루어지지 않고 유지 관리된다는 뜻으로 보인다.
    • 이어서 RestTemplate보다는 WebClient 사용을 권고하고 있다. 
    • 스프링 공식 문서(current, 23.8.27 기준)에 보면 NOTE: As of 5.0 this class is in maintenance mode, with only minor requests for changes and bugs to be accepted going forward. Please, consider using the org.springframework.web.reactive.client.WebClient which has a more modern API and supports sync, async, and streaming scenarios.라는 문장이 있다.
  • 비동기 호출을 지원하지 않는다.
    • 비동기 호출을 위한 AsyncRestTemplate가 따로 있다고 한다.

 

 

Spring WebClient

  • WebClient는 RestTemplate의 후속 버전으로 생각할 수 있으며, 비동기 네트워킹 및 스트림 처리를 위해 설계되었다.

🙂 장점

  • 비동기 및 Non-blocking I/O 지원으로 성능 향상이 가능하다.
  • 함수형 스타일로 코드 작성이 가능하다.
    • 가독성이 뛰어나다.

🙃 단점

  • 처음에 익숙해지는데 시간이 걸릴 수 있다.
    • Webflux에 대해 어느 정도 학습해야 하기 때문이다.
  • 오류 처리가 복잡할 수 있다.

 

 

Spring Cloud OpenFeign

  • Netflix에서 개발하였으며 현재는 Spring Cloud에서 관리하고 있다.
  • 선언적 웹 서비스 클라이언트이다.
    • 여기서 선언적이라는 의미는 애너테이션을 사용하는 것만으로 구현할 수 있다는 뜻이라고 한다.
    • Spring Data JPA에서 실제 쿼리를 작성하지 않고 interface만 지정하여 쿼리를 실행하는 구현체를 자동으로 만들어주는 방식과 유사하다.

🙂 장점

  • 인터페이스 기반의 개발로 코드가 간결하다.
  • Hystrix와 함께 사용하여 회복력 있는 마이크로서비스 구축이 가능하다.

🙃 단점

  • 설정 옵션이 복잡하다.
  • 디버깅하기 어려울 수 있다.

 

 

OkHttp

  • OkHttp는 Square에서 개발된 오픈 소스 HTTP 클라이언트 라이브러리이다.
  • 이 라이브러리는 HTTP/2를 지원하여 네트워크 통신의 성능을 향상하고, 인터셉터를 사용하여 네트워크 호출을 커스터마이징 할 수 있다.

🙂 장점

  • 모던 웹사이트와 서비스에 최적화된 HTTP/2와 SPDY 지원으로 성능 향상이 가능하다.
  • 인터셉터를 사용한 네트워크 호출 커스터마이징이 가능하다.
  • 타임아웃 설정 및 연결 재사용 등 고급 기능을 제공한다.

🙃 단점

  • 설정이 복잡할 수 있다.
  • 비동기 처리에 Callback 방식을 사용하므로 코드가 복잡해질 수 있다.

 

 

HttpClient

  • HttpClient는 Apache에서 제공하는 오픈 소스 라이브러리로 HTTP 프로토콜을 기반으로 서버와의 통신을 담당한다.
  • HttpClient 4.x 버전부터는 non-blocking I/O 모델을 지원한다.

🙂 장점

  • 많은 양의 데이터 전송에 적합한 스트림 방식을 제공한다.
  • 여러 가지 메서드(GET, POST 등)를 제공하여 다양한 요청 처리가 가능하다.
  • 로깅과 디버깅 용도로 상세한 정보를 제공한다.

🙃 단점

  • 초기 설정과 사용법이 복잡할 수 있다.
  • 동기 및 비동기 방식 모두 지원하지만, 비동기 방식은 별도의 라이브러리(HttpAsyncClient)가 필요하다.

 

📦 정리

  • 일단 설정이 복잡한 기술은 전부 제외하려고 한다.
  • 프로젝트 기한이 매우 짧고, 서버 간 통신 기능은 전체 프로젝트의 일부이기 때문이다.
    • 이보다 더 중요한 핵심 기능 구현에 집중해야 한다.
    • 여기서 중요한 점은 다른 기능은 Spring MVC를 기반으로 개발하고 있다는 점이다.
    • webflux는 러닝 커브가 있기 때문에 지금 API 서버 통신을 위해 Spring MVC 대신에 webflux로 전부 바꾸는 데에는 무리가 있어 보인다.
    • 두 기술은 동작 방법이 다르다.
      • Spring MVC의 경우 요청 당 하나의 스레드를 사용하는 동기 방식이고 Wevflux의 경우 이벤트 루프 기반의 비동기 방식이기 때문이다.
      • 두 가지 스레드 모델을 사용하면 예상치 못한 문제가 발생할 가능성이 있다.
  • 그럼에도 무엇을 사용하는 게 가장 이상적인지 판단하기 힘들어 뤼튼에게 물어보았다.

 

🤖 뤼튼의 답변

Spring Boot에서 외부 API 서버와 통신하는 데 가장 추천하는 도구는 상황에 따라 다릅니다. 그러나, 현재의 추세와 Spring의 공식 권장사항을 고려하면 WebClient를 추천합니다.

하지만 여전히 사용 사례나 특정 요구 사항에 따라 다른 도구가 더 적합할 수 있습니다. 예를 들어, Feign은 선언적 스타일로 인터페이스 기반의 개발이 가능하여 간결한 코드 작성을 원한다면 좋은 선택입니다. OkHttp나 HttpClient는 더 세밀한 컨트롤이 필요할 때 유용합니다.

따라서 어떤 도구를 선택할지 결정하기 전에 개별 프로젝트의 요구 사항과 각 도구의 장단점을 충분히 이해하는 것이 중요합니다.

 

  • 난이도만 생각하면 RestTemplate가 좋은 것 같다. 구현 자체는 매우 간단한 것처럼 보이기 때문이다. 그런데 유지 관리되고 있다고는 하나, 공식문서에서 조차 WebClient를 권장하고 GPT 역시 같은 의견인 것을 보니 외부 API 서버와의 통신에만 집중한다면 WebClient가 가장 이상적으로 보인다.
  • 한 가지를 더 고르자면 Open Feign일 것 같은데 구현시 에러 핸들링에 대한 자료의 양을 보기 위해 구글 트렌드를 검색해 보았다.

 

대한민국

  • it 기업이 밀집되어 있는 서울과 경기도에서 spring webclient의 검색 비율이 훨씬 높은 모습을 볼 수 있다.

 

전 세계

  • 중화권을 제외하고는 spring webclient가 압도적인 듯하다.

 

 

📌 Spring MVC와 Webflux의 공존 가능 여부

🤖 뤼튼의 답변

 Spring Web(MVC)와 Spring WebFlux를 한 프로젝트 안에서 동시에 사용하는 것은 기술적으로 가능합니다. 하지만 이 두 모듈이 제공하는 프로그래밍 모델이 서로 다르기 때문에(동기-블로킹 방식의 Spring MVC와 비동기-논블로킹 방식의 Spring WebFlux), 동시에 사용하려면 몇 가지 고려사항이 있습니다.

  1. 서버 환경: 기본적으로, Spring Boot는 classpath 상의 존재 여부에 따라 웹 애플리케이션을 실행하기 위한 서버 환경을 선택합니다. spring-webmvc가 classpath 상에 존재하면 Tomcat을, spring-webflux가 존재하면 Netty를 선택합니다. 둘 다 존재하는 경우 spring-webmvc가 우선시됩니다. 이런 동작은 application.properties나 프로그래밍적인 설정으로 변경할 수 있습니다.
  2. Controller 구현: Spring MVC Controller와 WebFlux Controller는 각각 Servlet API와 Reactive Streams API를 기반으로 하므로, 이 둘이 혼용되어 사용되는 것은 권장하지 않습니다.
  3. 프로그래밍 모델: Spring MVC는 전통적인 Servlet 스택과 함께 동기-블로킹 방식을, 반면에 WebFlux는 Reactive 스택과 함께 비동기-논블로킹 방식을 지원합니다. 이 두 가지 접근법은 각각 다른 프로그래밍 패러다임을 필요로 합니다.

 따라서 한 애플리케이션 내에서 두 가지 접근법을 혼합해서 사용하는 것보다는, 특정 서비스나 애플리케이션 단위에서 한 가지 접근법을 선택하여 일관성 있는 개발 경험을 제공하는 것이 좋습니다.

 

❓spring mvc 기반에 외부 api와 통신하는 일부 컨트롤러에서만 사용하려면 어떤 기술을 추천하는지?

🤖 뤼튼의 답변

 Spring MVC 기반의 애플리케이션에서 외부 API와 통신하는 일부 컨트롤러에서 사용하기에 가장 적합한 기술은 RestTemplate 혹은 Feign이 될 수 있습니다.

 

RestTemplate

  • Spring 3.0 부터 제공된 RestTemplate는 Spring MVC 애플리케이션에서 외부 RESTful 서비스를 호출하는데 많이 사용되었습니다. 이는 간단하고 직관적인 API를 제공하여 GET, POST, PUT, DELETE 등의 HTTP 메소드를 쉽게 사용할 수 있습니다.
  • 하지만 Spring 5.0 부터는 WebClient가 도입되면서 RestTemplate은 Deprecated 되었습니다. 그러나 아직까지도 많은 프로젝트에서 사용되고 있으며 잘 동작합니다.

Feign

  • Feign은 Spring Cloud 프로젝트의 일부로 통합되어 있어서, Hystrix(Circuit Breaker), Ribbon(Load Balancer) 등과 같은 다른 Netflix OSS와 함께 쉽게 사용할 수 있습니다.
  • 따라서 어떤 것을 선택할 지는 여러 가지 요소(프로젝트 요구사항, 개발 팀의 경험과 선호도 등)를 고려해야 합니다.

 

 

📜 결론

  • 처음 정리와는 달리 현재 내 상황에서는 RestTemplate의 사용이 가장 적절해보이기는 한다. GPT의 답변을 얼마나 신뢰할 수 있는지에 대한 문제와는 별개로 꽤 설득력있는 답변이라고 생각한다. 
  • 내일 출근해서 팀원분들에게 공유하고 의견을 듣고 결정하면 될 것 같다.

 

 

 

참고

뤼튼

구글 트렌드

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

https://jie0025.tistory.com/531

https://techblog.woowahan.com/2630/

728x90