[Spring]WebClient와 RestTemplate 어떤 것을 적용해야할까?

신창호·2024년 1월 26일
0

Spring

목록 보기
3/9

사이드 프로젝트를 진행하면서, 외부API를 가져와 가공할 작업이 생겨 어떻게 구현하지 고민중에 webClient와 RestTemplate에 대해 알게되었다.
Spring5이후부터, WebClient를 사용하는 것이 권장되었다고 하지만, RestTemplate을 한번 확인해보고 WebClient로 넘어가고 싶은 이상한 고집이 생겼다.(뭔가 내가 직접 체감하고 싶은마음..?)



게다가 RestTemplate와 달리 WebClient의 경우 비동기적인 방식으로 처리하여,Non-blocking과 비동기적 즉, 기다리지 않고 처리한다는 장점은 있으나, 보통 RDB(관계형 데이터베이스) 드라이버는 blocking 방식으로 동작하기때문에, 처리가 꼬이게된다.

  • 어차피 메인 스레드가 DB연산이 완료될때까지 기다린다.
    하지만 이것도 R2DBC(Reactive Relational Database Connectivity)라는 non-blocking전용 드라이버가 등장하였기 때문에, 사용은 가능하다.

그래서 이번 프로젝트에서, 아래 방법으로 진행해보고자 한다.
1. RestTemplate으로 먼저 구현해보고
2. 성능테스트
3. WebClient로 수정 (RDB -> R2DBC로 바꾸는 작업도 해볼 예정)
4. 성능테스트

이번 시간엔 간단하게 RestTemplate에 대해서만 알아보자

RestTemplate

  • RestTemplate은 Spring 3.0에서 도입된 클래스로써 스프링 프레임워크에서 HTTP 클라이언트를 쉽게 사용하기 위해 만들어졌다.
  • 이전에는 HTTP 클라이언트를 직접 구현해야 했지만, RestTemplate을 사용하면 HTTP 클라이언트를 쉽게 구현할 수 있다.
  • 기본적으로는 JSONXML을 지원한다.

사용법

  • 기본적으로 spring-webmvc 혹은 spring-boot-starter-web 의존성 추가하여야 한다.

    • spring-boot-starter-web에 포함된 RestTemplate은 spring-webmvc에 의존하고 spring-webmvc은 spring-web에 의존하고 있어 사실상, 똑같다.
    • spring-boot-starter-web =의존=> spring-webmvc =의존=> spring-web
  • HTTP 메소드

    • GET: getForObject(), getForEntity()
    • POST: postForEntity(), postForObject(), postForLocation()
    • PUT: put()
    • DELETE: delete()
  • 예시 코드(해당 url로 get요청보내는 코드)

    import org.springframework.http.ResponseEntity;
    import org.springframework.web.client.RestTemplate;
    
    public class RestTemplateExample {
        public static void main(String[] args) {
            RestTemplate restTemplate = new RestTemplate();
    
            String url = "http://example.com/users/{id}";
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class, "1");
    
            System.out.println(response.getBody());
        }
    }
    
    • 진짜 간단하게 new()로 생성하고, 사용하면 된다.

변경사항

  • Spring 5.x부터는 RestTemplate 보다 WebClient 사용이 권장되기때문에, 최신 버전의 Spring Boot에서는 RestTemplate이 자동으로 빈(Bean)으로 등록되지 않다.
    • 그래서 Lombok의 @RequiredArgsConstructor 사용한 DI 주입이 안됨
    • 빈으로 직접 등록하여 사용하거나 직접 생성자를 만들어주면 됨.
      @Configuration
      public class RestTemplateConfig {
      	@Bean
      	public RestTemplate restTemplate() {
      		return new RestTemplate();
      	}	
      }

성능테스트

  • 사실 성능테스트를 직접해볼려고 했으나, 사이드프로젝트를 해보다보니, RestTemplate의 이슈를 직접적으로 경험하게되었다.
  • 외부 API를 가공해서 Front에게 필요한 데이터만 보내야 했기 때문에, 하나의 요청에 여러작업을 한다.
  • 작업 리스트는 아래와 같다.
    1. 먼저 받은 고유 id로 matchID 데이터 30개를 끌어온다. : (matchId[30] 을 가지게됨)
    2. 그리고 다시 matchId 각각을 API요청하여 데이터를 가져온다.(요청 30번하게됨.)
    3. 가져온 데이터를 필요에 맞게 가공한다.
    4. 프론트한테 응답해준다.

결과

  • 요청 후, 응답시간 6~7초 걸림.
  • 동기적으로 데이터를 처리하기때문에,5건에 대략 1초씩 걸려, 순서대로 총 30번 요청을 하면 약 6초로 오래걸리는 것이다.(완전 비효울적..)
    • 그래서 비동기적 실행의 필요성을 느끼게 되었고, 기존의 코드를 WebClient로 전환하는 작업을 하려고 한다.

profile
한단계씩 올라가는 개발자

0개의 댓글