JUN0.DEV
JUN0.DEV

WebClient와 RestTemplate 선택 기준 정리

Published on
  • avatarJunyoung Yang

카카오테크캠퍼스 최종 프로젝트 UniSchedule에서는 외부 시간표 API를 호출해야 했다. 기능 자체는 외부 HTTP API를 호출해 응답을 가공하는 일이었지만, 이 호출이 서비스 핵심 흐름에 들어가기 때문에 클라이언트 선택을 가볍게 넘기기 어려웠다.

처음에는 익숙한 RestTemplate으로 빠르게 구현할 수 있었다. 하지만 프로젝트가 계속 유지된다고 가정하면, 공식 지원 방향과 타임아웃·재시도·커넥션 설정까지 함께 검토해야 했다. 이 글은 RestTemplateWebClient 중 무엇을 선택할지 정리한 기록이다.

처음 본 선택지

Spring에서 외부 HTTP API를 호출하는 방법은 여러 가지가 있지만, 당시 주로 비교한 것은 두 가지였다.

  • RestTemplate
  • WebClient

RestTemplate은 사용법이 단순하고 예제가 많다. 동기 MVC 기반 서비스에서 쓰기에도 직관적이다. 반면 WebClient는 WebFlux 계열 API라 처음에는 프로젝트 전체를 리액티브로 바꿔야 하는 것처럼 느껴질 수 있다.

하지만 실제 판단 기준은 "논블로킹이니까 WebClient"가 아니었다. 현재 프로젝트는 Spring MVC 기반이었고, 외부 API 호출 하나 때문에 전체 구조를 WebFlux로 바꿀 계획은 없었다.

처음 보인 문제

RestTemplate을 쓰면 빠르게 구현할 수 있었다. 다만 새 프로젝트에서 계속 가져가기에는 몇 가지 부담이 있었다.

  • 신규 기능 추가가 적극적으로 이뤄지는 클라이언트는 아니다.
  • 타임아웃, 커넥션 풀, 재시도 정책을 프로젝트 기준으로 명확히 잡아야 했다.
  • 이후 비동기 호출이나 스트리밍 요구가 생기면 다시 선택을 바꿔야 할 수 있었다.

외부 API 호출은 단순히 데이터를 받아오는 코드가 아니다. 장애가 나거나 응답이 늦어졌을 때 서비스 응답 시간 전체에 영향을 줄 수 있다. 그래서 호출 방식보다 운영 시 어떻게 제어할 수 있는지를 더 중요하게 봤다.

해결 방안

최종적으로는 외부 API 호출 클라이언트를 WebClient로 통일하는 방향을 선택했다.

선택 이유는 세 가지였다.

  • Spring의 최신 HTTP 클라이언트 방향과 더 잘 맞았다.
  • 타임아웃, 에러 처리, 필터, 헤더 설정을 명시적으로 구성하기 좋았다.
  • 이후 비동기 처리나 스트리밍이 필요해질 때 확장 여지가 있었다.

다만 여기서 주의한 점이 있다. WebClient를 쓴다고 해서 Spring MVC 기반 애플리케이션이 자동으로 논블로킹 서비스가 되는 것은 아니다. 호출부에서 block()을 사용하면 결국 해당 요청 흐름은 블로킹된다.

그래서 이번 선택은 "성능이 무조건 좋아진다"는 이유가 아니라, 앞으로의 지원 방향과 설정 유연성을 기준으로 한 선택에 가까웠다.

적용 및 구현

외부 API 호출 코드는 성공 케이스보다 실패 케이스가 중요했다. 그래서 아래 항목을 함께 확인했다.

  • 연결 타임아웃과 응답 타임아웃을 명시한다.
  • 외부 API 장애 시 내부 예외로 변환한다.
  • API 응답 스키마 변경에 대비해 매핑 경계를 둔다.
  • 호출 실패가 서비스 전체 장애로 번지지 않도록 처리한다.

이 기준을 두고 보면 WebClient를 단순히 한 줄 호출 도구로 쓰면 의미가 약했다. 클라이언트 빈 설정, 공통 에러 처리, 응답 매핑까지 함께 정리해야 선택의 이점이 생겼다.

트레이드오프

WebClient를 선택하면서 생긴 비용도 있었다.

  • spring-webflux 의존성이 추가된다.
  • 팀원이 리액티브 API에 익숙하지 않으면 학습 비용이 생긴다.
  • MVC 흐름에서 block()을 남발하면 논블로킹 장점은 거의 사라진다.

그래서 코드 리뷰에서는 WebClient를 사용했다는 사실보다, 어디까지 동기 흐름으로 둘지와 timeout/error handling을 어떻게 강제할지를 더 중요하게 봤다.

마무리

이 작업 이후 외부 API 클라이언트를 선택할 때는 익숙함만 기준으로 삼지 않는다.

정리한 기준은 아래와 같다.

  • 프로젝트가 Spring MVC인지 WebFlux인지 먼저 확인한다.
  • 클라이언트 선택보다 timeout, retry, error mapping이 더 중요하다.
  • WebClient를 쓰더라도 전체 흐름이 자동으로 논블로킹이 되는 것은 아니다.
  • 선택 이유는 코드에 남기거나 ADR처럼 기록해 두는 것이 좋다.

이번 선택은 최신 기술을 쓰기 위한 선택이 아니라, 외부 API 호출을 프로젝트 안에서 더 통제 가능하게 만들기 위한 선택이었다.