Programming/Spring

Spring - WebClient 사용해보기

긍정왕웹서퍼 2022. 5. 16. 00:17
728x90

개요

SpringBoot, Spring 환경에서 WebClient 를 사용하여 API Request 를 하는 클라이언트 프로젝트를 만들어보기.

서버와 API 통신을 위해 필요한게 무엇인지 알고 WebClient 의 기능사용해보기.

 

 

Why  ?

Web Flux

WebClient 란? Spring 5.0에서 추가된 interface 이다. 이전 버전에서는 클라이언트로 RestTemplate 를 사용했으나, 

비동기식 통신의 필요성으로 인해 WebClient 가 나오게 되었고, 현재 버전에서는 WebClient로 개발하는게 권장되는 상황이다.

그렇다면 RestTemplate 와 WebClient 가 어떤차이점이 있을까 ?

 

RestTemplate 와 WebClient 의 차이점을 보기쉽고 간편하게 볼 수 있도록 표로 비교해보자 

Rest Template Web Client
Blocking IO, 동기식(Synchronous) Non-Blocking IO, 비동기식(Asynchronous)
RESTful 원칙을 사용하며 단순화된 통신 JSON, XML 을 쉽게 받고 응답
멀티쓰레드 방식 싱글쓰레드 방식 
JAVA Servlet API  Spring Reactive Framwork

 

그리고 가장 중요한 점은 당장 RestTemplate 로 구현한 코드를 바꿀필요는 없지만, Spring 5.0 이후 버전에서 

RestTemplate가 Deprecated 되었고, 앞으로 개발이 필요한 Client 의 경우 WebClient 를 사용하는 것이 좋다는 점이다.

 

그렇다면 어떻게 WebClient 를 사용할 수 있을지 알아보자.

 

 

 

의존성 설정

Gradle


implementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '2.6.7'

 

Maven


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <version>2.6.7</version>
</dependency>

 

 

 

구현

String response = WebClient.create()
                    .post()
                    .uri("http//test.com")
                    .contentType(MediaType.APPLICATION_JSON) // Request Type JSON
                    .acceptCharset(Charset.forName("utf-8")) // CharSet Setting
                    .body(BodyInserters.fromMultipartData(builder.build())) // body : Request Params key&value , content type 'urlencode'
                    .retrieve().bodyToMono(String.class)
                    .block();

 

 

위 코드의 내용을 차근차근 살펴보자.  

String response = WebClient.create()

 

먼저 WebClient.create() 를 통해 클라이언트를 생성한다고 선언하며, 

 

.post()
.uri("http//test.com")

Request 를 보낼 Method가 Get, Post, Put, Delete 중 무엇인지 Method를 선언하고, 보내는 URL을 입력합니다. 

.contentType(MediaType.APPLICATION_JSON) // Request Type JSON
.acceptCharset(Charset.forName("utf-8")) // CharSet Setting

혹시모를 상황에 대비해서 Content Type 과 Charset 설정을 위해 위와같이 JSON, UTF-8 이라는 설정을 추가합니다.

 

그리고 body,  head등에 필요한 내용을 담을 수 있으나, 예제에서 저는 body만 사용했습니다.

.body(BodyInserters.fromMultipartData(builder.build())) // body : Request Params key&value , content type 'urlencode'

그리고 body에 BodyInserters.fromMultipartData 를 사용했는데, 이는 Body 에 File등 여러가지 타입의 정보를 넣어야할 때 

반응 스트림, 서버 전송 이벤트, 리소스 등과 같은 다양한 본문을 작성하는 코드를 구현하기 위해 필요합니다. 그리고 그 안에 

bulider.build() 를 사용했는데 예제의 경우 body를 JSON이 아닌 urlencode type으로 보내야했기때문에 builder를 사용했는데,

기본적으로 WebClient 에서는 JSON타입으로 DTO, 객체등 다양한 타입을 지원하기 때문에 별다른 처리를 안해줘도 되는 경우가 있다.

 

 

.retrieve().bodyToMono(String.class).block();

 

마지막으로 retrieve() 메소드는 내가 결과값으로 받을 응답값을 추출하는 방법을 선언하기 위한 chaning method이다.

toEntity() , bodyToMono(), bodyToFlux(),  등 다양한 방식으로 얻을 수 있는데,

Mono 가 무엇이냐면, 한개의 값만 리턴받으면 될 때 사용하며 복수의 리턴값을 받아야 할 경우에는 bodyToFlux 를 사용한다.

 

 

이처럼 하나하나 사용해보면 매우 직관적인 메소드를 지원하여 간편하게 Client를 구현할 수 있고, 비동기식의 안정적인 요청과 응답을 통해 서버에 가하는 리소스가 줄어들어 매우 효과적이다. 

Spring이 새삼 얼마나 큰 Framework 인지 실감하는 부분이다.. 공부해야할게 많다.

 

 

 

 

 

 

참조 

https://madplay.github.io/post/difference-between-resttemplate-and-webclient

https://tecoble.techcourse.co.kr/post/2021-07-25-resttemplate-webclient/

https://heekim0719.tistory.com/425