스프링 앱에서 다른 서버의 REST API를 부르는 도구는 여러 세대가 있다. 지금 새 코드라면 동기 호출은 RestClient, 리액티브·비동기는 WebClient, 인터페이스 선언 방식은 HTTP Interface나 OpenFeign이 흔한 선택이다(2026 기준).
| 도구 | 방식 | 상태 |
|---|---|---|
| RestTemplate | 동기, 템플릿 메서드(template method) | 퇴장 예정. 7.0에서 폐기 예고, 7.1(2026-11)에서 @Deprecated, 8.0에서 제거 계획(2026 기준). 새 코드는 RestClient |
| WebClient | 논블로킹(non-blocking), 리액티브(Mono·Flux) | WebFlux 모듈. 동기 코드에서 .block()으로도 쓸 수 있다 |
| RestClient | 동기, 플루언트(fluent) API | 스프링 6.1에서 추가. RestTemplate의 현대적 대체 |
| HTTP Interface(HTTP Service Client) | 인터페이스 선언 → 프록시 생성 | 스프링 6 기본 기능 |
| OpenFeign | 인터페이스 선언 → 프록시 생성 | Spring Cloud 프로젝트 |
RestClient client = RestClient.builder()
.baseUrl("https://api.example.com")
.defaultHeaders(h -> h.setBasicAuth(user, password))
.build();
UserDto user = client.get().uri("/users/{id}", id)
.retrieve()
.body(UserDto.class);@FeignClient(name = "users", url = "${users.base-url}")
public interface UserClient {
@GetMapping("/users/{id}")
UserDto get(@PathVariable Long id);
}- 인터페이스 방식은 리포지터리처럼 선언만 하면 구현을 만들어 준다. 호출부가 HTTP 세부를 몰라도 된다
- 클라이언트 빈은 하나 만들어 재사용한다. 커넥션 풀(connection pool)이 함께 재사용된다
- 연결·읽기 타임아웃(connect timeout, read timeout)을 반드시 정한다. 기본값이 무한대에 가까운 경우가 있어, 느린 다운스트림 하나가 내 스레드를 모두 붙잡는다
- 재시도는 멱등한 요청에만 하고, 상대가 요청 제한을 걸면
Retry-After를 따른다 - 비밀값(API 키, 기본 인증 정보)은 설정에서 주입받는다(스프링 설정 외부화와 프로파일)
브라우저에서 부르는 경우와 서버 간 호출의 차이(CORS(Cross-Origin Resource Sharing)가 적용되지 않는 등)는 브라우저 요청과 서버 간 요청를 본다. 내부 서비스끼리 고성능 통신이 필요하면 gRPC도 후보다.
출처: The state of HTTP clients in Spring · Spring Framework 문서: RestClient · WebClient · RestTemplate · HTTP Service Client