Programing/Java & Spring

세무민의 코딩일기 : Spring WebClient에 대해 알아보자

세기루민 2025. 3. 10. 12:30
728x90

안녕하세요 세기무민입니다.

 

RestTemplate deprecated 된다는 걸 알고 있었으나, 따로 WebClient에 대한 포스팅을 한 적이 없던거 같아서

오랜만에 한번 포스팅을 해보려고 합니다.

1. Spring WebClient?

Spring 프레임워크에서 제공하는 비동기 및 논블로킹 방식의 반응형 HTTP 클라이언트를 의미

  • 비동기와 논블로킹을 통해 대규모 트래픽을 효율적으로 처리가 가능하며 MSA 환경 혹은 고성능 어플리케이션에서
    유용함

Spring WebFlux 모듈의 일부이며, 기존 Restemplate를 대체하기 위해 설계됨

 

2. Spring WebClient vs RestTemplate

특징 WebClient RestTemplate
동작 방식 비동기, 논블로킹 동기, 블로킹
기반 기술 WebFlux (반응형) Servlet (전통적)
성능 높은 확장성 제한적
지원 Spring 5+ (권장) Spring 3+ (레거시)

 

3. 특징

1) 비동기 & 논블로킹

Netty 기반으로 스레드 블록 없이 요청을 처리.

2) 반응형 스트림

MonoFlux를 활용해 단일/다중 응답 처리.

3) 유연한 설정

타임아웃, 헤더, 에러 처리 등을 쉽게 커스터마이징

4) HTTP/2 지원

최신 프로토콜과 WebSocket도 사용 가능.

 

4. 예시 코드

4.1) build.gradle 

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
}

 

  • WebClient 사용을 위해서는 WebFlux 의존성 추가 필요

 

4.2) Get 방식으로 호출

import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

public class WebClientGetMethodConfig {
    public static void main(String[] args) {
        WebClient webClient = WebClient.create("https://sg-moomin.tistory.com");

        String baseUri = "/v1/tistory/post/";
        
        Mono<String> response = webClient.get()
                .uri(baseUri)          			// 엔드포인트 설정
                .retrieve()               		// 응답 가져오기
                .bodyToMono(String.class) 		// JSON을 String으로 변환
                .doOnError(error -> System.err.println("Error: " + error.getMessage()));

        response.subscribe(System.out::println); // 응답 출력
    }
}
  • retrieve() : API 호출 시 서버로 요청을 보내고 응답 본문을 가져올 수 있도록 지원하는 메서드 
  • bodyToMono : 응답 본문을 자바 객체로 변환하는 역할

 

4.3) Post 방식으로 호출

import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

public class WebClientPostMethodConfig {
    public static void main(String[] args) {
        WebClient webClient = WebClient.create("https://sg-moomin.tistory.com");

        RequestDto requestdto = requestdto.builder.title("sgmoomin").build();                           
        String baseUri = "/v1/tistory/post/finds";

        Mono<String> response = webClient.post()
                .uri(baseUri)
                .header("Content-Type", "application/json")
                .bodyValue(requestdto, RequestDto.class)    // 요청 본문 설정
                .retrieve()
                .bodyToMono(RequestDto.class);

        response.subscribe(System.out::println);
    }
}
  • bodyValue : 요청 본문 설정할 때 사용되는 메서드

 

5. WebClient 자주 사용되는 메서드 

1) WebClient TimeOut

WebClient webClient = WebClient.builder()
        .baseUrl("https://sg-moomin.tistory.com")
        .clientConnector(new ReactorClientHttpConnector(
            HttpClient.create().responseTimeout(Duration.ofSeconds(5)) // 5초 타임아웃
        ))
        .build();
  • 외부 API 호출 시 타임 아웃 설정 필요하며, 이는 responseTimeout을 통해 설정이 가능

2) Exception 처리

Mono<String> response = webClient.get()
        .uri("/invalid-endpoint")
        .retrieve()
        .onStatus(HttpStatus::is4xxClientError, 
            res -> Mono.error(new RuntimeException("4xx 에러 발생")))
        .bodyToMono(String.class);
  • API 호출 시 발생되는 Exception 처리를 할 수 있음

 

3) Retry

Mono<String> response = webClient.get()
        .uri("/unstable-endpoint")
        .retrieve()
        .bodyToMono(String.class)
        .retry(3); // 최대 3번 재시도
  • retry 설정을 통해 호출이 정상적으로 안되었을 경우 재호출 가능
728x90