WebClient
- 비동기적이고 non-blocking 방식으로 HTTP 요청을 처리할 수 있는 클라이언트
- 전통적인 Spring MVC의 RestTemplate의 대안으로 Spring 5부터 지원하는 non-blocking HTTP 요청을 위한 리액티브 웹 클라이언트로서 함수형 기반의 향상된 API 제공
- 비동기적 호출 외에도 block() 메서드를 사용하여 동기적으로 데이터를 받을 수 있지만 WebFlux 환경에서는 가능한 비동기 방식으로 사용하는 것이 성능에 유리
- WebFlux 환경에서의 고성능, 비동기적 애플리케이션 개발을 위해 설계됐으며 기본 HTTP 클라이언트 라이브러리는 Reactor Netty
- WebClient는 Mono와 Flux를 지원하여, 리액티브 스트림을 통해 데이터를 처리
- Mono는 하나의 요소를 반환할 때 사용
- Flux는 여러 요소를 처리할 때 사용
WebClient 코드 예시 및 사용법
- Spring에서 지원하는 ApplicationRunner를 이용해 도서 정보 샘플 애플리케이션이 실행되는 시점에 총 네 번의 HTTP 요청을 전송하도록 설정
1. exampleWebClient01 메서드 설명
- 테스트 대상인 BookRouter의 POST()로 전송할 request body를 작성
- WebClient.create() 메서드를 통해 WebClient 인터페이스의 구현 객체 생성
- post() 메서드를 통해 HTTP 메서드 타입을 POST로 지정
- uri() 메서드로 request를 전송할 URI 지정
- bodyValue() 메서드로 request body를 설정하며 bodyValue() 메서드는 body(BodyInserter)의 단축 메서드
- retrieve() 메서드는 응답을 어떤 형태로 얻을지에 대한 프로세스의 시작을 선언하는 역할
- toEntity(Void.class) 메서드는 파라미터로 주어진 클래스의 형태로 변환한 response body가 포함된 ResponseEntity 객체를 반환
- BookHandler의 createMember() 메서드가 반환하는 ServerResponse에 body 데이터가 추가되지 않기 때문에 toEntity()의 파라미터는 Void.class가 됨
- 최종 응답으로 전달받은 Mono<ResponseEntity<Void>>를 구독하여 응답으로 전달받은 status code와 location header 정보를 로그로 출력
2. exampleWebClient02 메서드 설명
- 테스트 대상인 BookRouter의 PATCH()로 전송할 request body를 작성
- WebClient.create(baseUrl) 메서드를 통해 WebClient 인터페이스의 구현 객체 생성
- patch() 메서드를 통해 HTTP 메서드 타입을 PATCH로 지정
- uri() 메서드로 요청을 전송할 URI를 지정하며 path variable이 포함된 URI의 경우 Varargs의 형태로 path variable 값 전달
- bodyToMono()를 통해 response body를 파라미터로 전달된 타입의 객체로 디코딩
3. exampleWebClient03 메서드 설명
- get() 메서드를 통해 HTTP 메서드 타입을 GET으로 지정
- uri() 메서드로 요청을 전송할 URI를 지정하며 uriBuilder를 통해 path variable의 값을 포함한 URI를 생성
4. exampleWebClient04 메서드 설명
- uri() 메서드로 요청을 전송할 URI를 지정하며 uriBuilder의 queryParam() 메서드를 이용해 페이지네이션을 위한 쿼리 파라미터인 page와 size의 값을 포함한 URI 생성
- bodyToFlux()를 통해 response body를 파라미터로 전달된 타입의 객체로 디코딩
- bodyToFlux()는 bodyToMoo()와 달리 자바 컬렉션 타입의 response body 수신
WebClient Connection Timeout 설정
- WebClient는 특정 서버 엔진의 HTTP Client Connector 설정을 통해 HTTP Connection에 대한 timeout을 설정 가능
코드 설명
- option() 메서드로 Connection 설정을 위한 HTTP Connection이 연결되기까지의 시간인 timeout 시간 설정
- responseTimeout() 메서드로 응답을 수신하기까지의 Timeout 시간 설정
- doOnConnected()의 파라미터로 전달되는 람다 표현식을 통해 Connection이 연결된 이후에 수행할 동작 정의
- 특정 시간 동안 읽을 수 있는 데이터가 없을 경우 ReadTimeoutException 예외를 발생시키는 ReadTimeoutHandler 등록
- 특정 시간 동안 쓰기 작업을 종료할 수 없을 경우 WriteTimeoutException을 발생시키는 WriteTimeoutHandler 등록
- WebClient의 객체는 Builder 패턴을 통해서도 생성할 수 있는데 이 경우 clientConnector() 메서드를 이용해 앞에서 설정한 서버 엔진의 HTTP Client Connector 설정
- 여기서는 Reactor Netty에서 제공하는 HttpClient 객체를 생성자 파라미터로 가지는 ReactorClientHttpConnector를 설정
exchangeToMono()를 사용한 응답 디코딩
- retrieve() 대신에 exchangeToMono()나 exchangeToFlux() 메서드를 이용하면 response를 사용자의 요구 조건에 맞게 제어 가능
코드 설명
- exchangeToMono()를 통해 응답을 수신한 다음 HttpStatus가 CREATED이면 ResponseEntity를 반환하고 그 외에는 Exception을 던지도록 처리
- ClientResponse의 createException() 메서드는 request/response 정보를 포함한 WebClientResponseException 생성
참고
- 스프링으로 시작하는 리액티브 프로그래밍 (황정식 저자)
반응형
'Spring > 스프링으로 시작하는 리액티브 프로그래밍' 카테고리의 다른 글
[Spring WebFlux] Reactive Streaming 데이터 처리 (0) | 2024.10.08 |
---|---|
[Spring WebFlux] 예외 처리 (0) | 2024.09.16 |
Spring Data R2DBC 간단 정리 (0) | 2024.09.11 |
[Spring WebFlux] 함수형 엔드포인트(Functional Endpoint) (0) | 2024.09.06 |
[Spring WebFlux] 애너테이션 기반 컨트롤러 (0) | 2024.08.20 |