2 minute read

스프링 어플리케이션에서 HTTP 요청을 할때 사용하는 방법으론 RestTemplate과 WebClient가 있다. 스프링 5.0 이전까지는 클라인트에서 Http 접근을 위해 RestTemplate였고, 스프링 5.0 부터 WebClient가 나와 현재는 WebClient를 사용하기를 권장하고 있다. (바로 이전 포스트에서 AsyncRestemplate가 Deprecated된 내용을 다루었다)

이번 포스트에선 Restemplate와 WebClient에는 어떠한 특징드리 있으며 왜 WebClient를 사용하길 권고 하는지 알아본다.

0. 목차

  1. RestTemplate
  2. WebClient
  3. RestTemplate와 WebClient의 차이
  4. 성능비교
  5. 참고

1. RestTemplate

스프링 3.0 부터 지원하던 RestTemplate는 Http 통신에 유용하게 쓸수 있는 템플릿이다. REST 서비스를 호출하도록 설계되어 HTTP 프로토콜의 메서드 (GET, POST, DELETE, PUT) 에 맞게 여러 메서드를 제공한다.

RestTemplate 특징

  • 통신을 단순화 하고 RESTful 원칙을 지킨다.
  • 멀티쓰레드 방식을 사용한다.
  • Blocking 방식을 사용한다.

의존성 설정

기본 스프링 부트 의존성을 추가하면 RestTemplate 관련 의존성은 자동으로 추가된다. 따라서 스프링 부트를 사용한다면 추가의 설정이 필요하지는 안흔다.

implementation 'org.springframework.boot:spring-boot-starter-web'

RestTemplate의 사용

RestTemplate를 생성할 때

  • HttpClent
  • ClientHttpRequestFactory 를 전달하여 지정할 수 있다. 기본 생성자의 경우 내부적으로 ClientHttpRequestFactory의 구현체 SimpleClientHttpRequestFactory를 사용하여 초기화 한다.

RestTemplate의 생성

@Configuration
public class RestTemplateClient {

   @Bean
   public RestTemplate restTemplate(RestTemplateBuilder builder) {
      return builder.build();
   }
}

RestTemplate를 생성할떄는 builder를 통하여 생성해 줄수 있다. builder를 통해 생성하고 스프링 빈으로 사용할 수 있도록 생성해준다.

public TestClass {
   @Autowired
   RestTemplate restTemplate;

   public TestClass(RestTemplate restTemplate) {
      this.restTemplate = restTempalte;
   }

   public String getSthFromServer(){
        return restTemplate.getForObject("https://example.com" ,String.class);
    }
}

RestTemplate 메소드

  • getForObject(GET): 주어진 URL 주소로 HTTP GET 메서드로 객체로 결과를 받는다.
  • getForEntity(GET): 주어진 URL 주소로 HTTP GET 메서드로 ResponseEntity로 반환을 받는다.
  • postForLocation(POST): POST 요청을 보내고 결과로 헤더에 저장된 URI 결과로 반환 받는다.
  • postForObject(POST): POST 요청을 보내고 객체로 결과를 반환 받는다.
  • postForEntity(POST): POST 요청을 보내고 ResponseEntity로 반환 받는다.
  • delete(DELETE): 주어진 URL 주소로 HTTP DELETE 메서드를 실행한다.
  • handForHeader(HEADER): 헤더의 모든 정보를 얻을 수 있으면 HTTP HEAD메서드를 사용한다.
  • put(PUT): 주어진 URL 주소로 HTTP PUT 메서드를 실행한다.
  • patchForEntity(PATCH): 주어진 URL 주소로 HTTP PATCH 메서드를 실행한다.
  • optionForAllow(OPTIONS): 주어진 URL 주소에서 지원하는 HTTP 메서드를 조회한다.
  • exchange(any): HTTP 헤더를 새로 만들수 있고 어떤 HTTP 메서드도 사용이 가능하다.
  • execute(any): Request/Response 콜백을 수정할 수 있다.

2. WebClient

WebClient란?

WebClient는 스프링 5.0에 추가된 인터페이스이다. 스프링 5.0이전에는 비동기 클라이언트로 AsyncRestTemplate를 사용했다. 하지만 스프링 5.0 이후부터는 WebClient를 사용할 것을 권장한다 (아예 deprecated 되었다)

WebClient 특징

  • 싱글 스레드 방식을 사용
  • Non-Blocking 방식 사용
  • Json, XML을 쉽게 응답받는다.

Non-Blocking?

시스템을 호출한 직후에 프로그램으로 제어가 다시 돌아와서 시스템 호출의 종료를 기다리지 않고 다음 동작을 진행한다. 호출한 시스템의 동작을 기다리지 않고 동시에 다른 작업을 진행할 수 있어서 작업의 속도가 빨라진다는 장점이 있다.

의존성 설정

WebClient를 사용하기 위해서는 RestTemplate와 달리 의존성을 추가해야 할 부분이 있다. webflux의 의존성을 추가해 주야 한다. Gradle기준으로 아래와 같이 의존성을 추가해 주면 된다.

// webflux
implementation 'org.springframework.boot:spring-boot-starter-webflux'

WebClient 생성

WebClient를 생성하는 데는 2가지 방법이 있다.

  • WebClient.create();
  • Builder를 활용한 클래스 생성
Webclient webClient = WebClient
	                    .builder()
	                    .baseUrl("http://localhost:8080")
	                    .defaultCookie("쿠키","쿠키값")
	                    .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
	                    .build();

Request 요청하기

WebClient.RequestHeaderUriSpec<?> baseSpec = Webclient.builder();
// baseSpec에 원하는 파라미터를 추가로 붙여서 요청한다. 
baseSpec.uri(builder -> builder.path("/")
                               .queryParam("이름","값")
                               .builder()
                        )
                        .retrieve() // Response를 받아옴.

Response 받아오기

  • exchange() -> ClientResponse를 상태값 그리고 헤더와 함께 가져온다.
  • retrieve() -> body를 바로 가져온다.
    String response = weclient.exchange().block().bodyToMono(Sting.class).block();
    String resposne2 = weblclient.retrieve().bodyToMono(String.class).block();
    

bodyToMono는 가져온 body를 Reactor의 Mono 객체로 바꿔준다. Mono 객체는 0-1개의 결과를 처리하는 개체이다. Flux는 o-N 개의 결과를 처리하는 객체이다.

위처럼 block()을 사용하면 RestTemplate처럼 동기식으로 사용이 가능하다.

3. RestTemplate과 WebClient의 차이

RestTemplate와 WebClient의 가장 큰 차이점은 Non-Blocking과 비동기화 가능 여부이다. 결국 이러한 차이점이 스프링에서 RestTemplate을 사용하는것 보다 WebClient의 사용을 권장하는 이유이다. 스프링 4.0에서 AsyncRestTemplate을 잠시 지원했지만 지금은 deprecated 되었다.

4. 성능 비교

Boot1 은 RestTemplate을 사용하고 Boot2 는 WebClient 를 사용한다. 동시 사용자가 1,000명까지는 처리속도가 거의 비슷하지만 그 이후에서는 RestTemplate(Boot1) 이 급격하게 느려지는 것을 볼 수 있다. 동시 사용자의 규모가 별로 없다면 RestTemplate을 사용하는 것은 별문제 없지만 어느정도의 규모가 있다면 WebClient를 선택하는 것이 바람직해 보인다.

4. 참고

https://tecoble.techcourse.co.kr/post/2021-07-25-resttemplate-webclient/ https://juneyr.dev/2019-02-12/resttemplate-vs-webclient https://www.baeldung.com/spring-webclient-resttemplate https://happycloud-lee.tistory.com/220

Categories:

Updated: