
이번 데브코스 2차 프로젝트에서는 Open AI API와 Tosspayment API를 도입하여 기능을 구현하였다.
이 과정에서 외부 API와 연동할 때 사용되는 WebClient와 RestClient 차이점에 대해 궁금했기에 해당 글로 정리해보도록 하겠다!
Spring에서는 외부 API를 호출하기 위해 WebClient, RestClient, RestTemplate 등 HTTP Client가 사용된다.
RestTemplate 같은 경우에는 요즘에는 사용을 잘 안 하는 편이고 보통 WebClient, RestClient가 가장 많이 쓰인다. 각각의 특징이 무엇인지, 어떻게 사용하는지, 어떤 상황에 사용하면 좋을지에 대해 정리해보겠다.
Spring 3.0부터 제공된 HTTP 클라이언트이다.
사용법은 간단하지만 Spring 5.0 이후부터는 유지보수만 진행 중인 클라이언트이다
동기(Blocking) 방식으로 작동하기 때문에 요청이 많아지면 성능상 병목이 발생할 수 있다.
또한 간단하지만 요청이 완료될 때까지는 스레드가 대기하기 때문에 비동기 처리나 고성능 서버에서는 한계가 있다.
따라서 Spring 5.0부터 새로운 방식들이 등장하게 된다.
🧩 예시 코드
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
WebClient는 Spring 5.0에서 도입된 리액티브 기반 HTTP 클라이언트이다.
webflux 의존성을 추가해야 사용할 수 있으며, 비동기(Non-blocking) 방식으로 요청을 처리한다.
💬 의존성
implementation("org.springframework.boot:spring-boot-starter-webflux")
🧩 예시 코드
WebClient webClient = WebClient.create();
Mono<String> response = webClient.get()
.uri("https://api.example.com")
.retrieve()
.bodyToMono(String.class);
✅ 장점
⚠️ 단점
📌 추천 상황
여러 외부 API를 동시에 호출하거나, 실시간으로 데이터를 처리해야 하는 대규모 트래픽 환경에 적합
Spring 6.0에서 등장한 RestTemplate의 후속작이다.
동기(Blocking) 방식이지만 훨씬 간결하고 직관적인 API 설계로 개선되었다.
WebClient와 달리 별도의 의존성 추가가 필요없다.
🧩 예시 코드
RestClient restClient = RestClient.create();
String response = restClient.get()
.uri("https://api.example.com")
.retrieve()
.body(String.class);
✅ 장점
⚠️ 단점
📌 추천 상황
간단한 REST API 호출, 인증 서버 등 단일 요청 중심의 API 통신
| 구분 | WebClient | RestClient |
|---|---|---|
| 등장 시기 | Spring 5 | Spring 6 |
| 처리 방식 | 비동기 (Reactive) | 동기 (Blocking) |
| 의존성 | spring-boot-starter-webflux | spring-boot-starter-web |
| 기반 기술 | Reactor (WebFlux) | RestTemplate 개선 버전 |
| 성능 | 고성능, 병렬 처리 유리 | 단순 요청에 적합 |
| 복잡도 | 비교적 높음 | 매우 간결 |
| 추천 상황 | 여러 외부 API를 병렬 호출할 때 | 단일 요청/응답 처리할 때 |
간단하게 말하자면 동기(Synchronous)식은 요청을 보낸 뒤 응답이 올때까지 기다리는 것이고, 비동기(Asynchronous)식은 요청을 보내고 기다리지 않고 다른 작업을 수행하는 것이다.
| 구분 | 동기 (Synchronous) | 비동기 (Asynchronous) |
|---|---|---|
| 처리 방식 | 요청을 보낸 뒤, 응답이 올 때까지 기다림 | 요청을 보내고 기다리지 않고 다음 작업 수행 |
| 예시 | 전화 통화 — 상대가 받을 때까지 기다림 | 문자 메시지 — 보내고 나중에 답장을 받음 |
| 스레드 점유 | 응답이 올 때까지 스레드가 대기 | 스레드는 대기하지 않고 다른 일 수행 가능 |
| 장점 | 코드가 단순하고 직관적 | 성능 향상, 높은 동시성 처리 가능 |
| 단점 | 처리량이 적고, 병목 발생 가능 | 코드 복잡도 증가, 디버깅 어려움 |
리액티브 프로그래밍은 데이터 흐름과 변화에 반응하는 프로그래밍 패러다임이다.
즉, "무언가 바뀌면 그에 따라 자동으로 반응하는 구조"이다.
Spring에서는 이 개념은 Reactor 라이브러리(Mono, Flux) 를 통해 구현하며, WebClient가 바로 이 리액티브 스트림을 기반으로 동작한다.
Mono<String> response = webClient.get()
.uri("https://api.example.com")
.retrieve()
.bodyToMono(String.class);
이 코드는 데이터가 도착하면(Mono가 완료되면) 그때 반응하라는 의미이다.
즉 요청 -> 대기 -> 응답의 흐름을 기다리지 않고 응답이 준비되면 알아서 처리해주라는 이벤트 기반 비동기 방식이다.