WebClient 이해하기

WebClient 란

  • API를 호출하기 위해 사용되는 Http Client 모듈 중 하나
 

왜 WebClient 가 필요한가

  • 자바에서 많이 사용하는 Http Client 는 RestTemplate 이다. Spring 5.0 버전부터 RestTemplate 은 유지 관리 모드로 변경되었고, 대안으로 WebClient 사용을 강력히 권고하고 있다. WebClient 는 논블로킹/블로킹 모두 지원한다.
 

동작 원리

  • Single-Thread, Not-Blocking
  • 이벤트 반응형으로 동작
  • Spring Web Reactive 모듈에 포함
  • React Web 프레임워크인 Spring WebFlux 에서 Http Client 로 사용됨
 

공식 문서

 

WebClient 예제

package com.study.webclient_test.api;

import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;

@Slf4j
@RestController
public class WebClientController {

    @GetMapping("/test2")
    public Mono<String> doTest() {
        HttpClient httpClient = HttpClient.create()
                .tcpConfiguration(
                        client -> client.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000) //miliseconds
                                .doOnConnected(
                                        conn -> conn.addHandlerLast(new ReadTimeoutHandler(5))  //sec
                                                .addHandlerLast(new WriteTimeoutHandler(60)) //sec
                                )
                );

        WebClient client = WebClient.builder()
                .baseUrl("http://localhost:5011")
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build();

        return client.get()
                .uri("/webclient/test-builder")
                .retrieve()
                .bodyToMono(String.class);
    }
}
 
  • HttpClient 는 연결하는 클라이언트를 설정한다. 연결시 옵션 등을 설정할 수 있다.
  • baseUrl() : 호출할 Host 를 지정한다.
  • retrieve() : Body 만 가져온다. 
  • bodyToMono() : 값 변환을 어떤 것으로 할지 정한다.
 

Response 를 받아오기

  • retrieve : Body 만 가져온다
  • exchange : ClientResponse 를 상태값 그리고 헤더와 함께 가져온다.
 

Response 값 변환

  • bodyToMono : Mono<T>
  • bodyToFlux : Flux<T>
  • toEntity : Mono<ResponseEntity<T>>
 

논블록킹 및 블록킹

  • subscribe : 논블로킹
  • block : T 변환, 블로킹
  • toStream : Stream<T> 변환 - 블로킹