- Spring 6의 REST Clients 3가지2023년 03월 13일
- starryeye
- 작성자
- 2023.03.13.:07
이번 포스팅에서는 Spring 6 의 REST Clients 3가지를 예제를 통해 알아보겠다.
Spring 공식 문서에 따르면 아래와 같이 소개하고 있다.
The Spring Framework provides the following choices for making calls to REST endpoints:
1. RestTemplate - synchronous client with template method API.
2. WebClient - non-blocking, reactive client w fluent API.
3. HTTP Interface - annotated interface with generated, dynamic proxy implementation.
하나씩 예제로 다뤄보자..
예제에서 사용할 외부 API는 아래와 같다.
https://open.er-api.com/v6/latest
-> USD 기준의 다른 통화와의 환율 정보를 조회 한다.
1. RestTemplate
RestTemplate 은 Spring 3.0 버전 부터 존재 했었다.
현재 Spring 6 버전 기준으로 deprecated 되어있지 않다.(과거에 잠시 deprecated 였으나 바뀜)
특징
- 멀티 쓰레드 방식을 지원하여, RestTemplate 객체를 쓰레드간 공유가 가능하다.
- 동기 방식
- RestTemplate 생성 시 어떤 HttpClient, ClientHttpRequestFactory 를 사용하여
생성 할 것인지 선택 할 수 있다.
(기본 생성자를 사용하면 SimpleClientHttpRequestFactory 가 선택된다.)
Spring은 기본적으로 ClientHttpRequestFactory 로 아래를 제공한다.
- Apache HttpComponents
- Netty
- OkHttp
예를 들어 Apache HttpComponents 를 통해 생성한다면 아래와 같다.HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); factory.setReadTimeout(5000); // 최대 읽기 시간, ms factory.setConnectTimeout(3000); // 최대 연결 시간, ms HttpClient httpClient = HttpClientBuilder.create() .setMaxConnTotal(100) // connection pool, 최대 연결 유지 갯수 .setMaxConnPerRoute(50) // connection pool, 특정 경로당 최대 연결 유지 갯수 .build(); factory.setHttpClient(httpClient); // HttpClient Set RestTemplate restTemplate = new RestTemplate(factory);
HttpClient 로 Connection Pool 관련 옵션 셋팅이 가능하다.
외부 환율 API 예제 코드RestTemplate rt = new RestTemplate(); Map<String, Map<String, Double>> res = rt.getForObject("https://open.er-api.com/v6/latest", Map.class); System.out.println(rest.get("rates").get("KRW")); //출력 : 1318.986681
위와 같이 RestTemplate 로 동기식 통신을 하여 응답을 받을 수 있다.
(예제에선 HTTP GET Method 를 사용하여 객체로 바인딩하여 리턴되는 getForObject 를 사용했다.)
RestTemplate Method
2. WebClient
Spring 5.0 버전에서 추가된 인터페이스이다.
특징
- Non-blocking I/O
- Reactive Streams back pressure
- High concurrency with fewer hardware resources
- Functional-style, fluent API that takes advantage of Java 8 lambdas
- Synchronous and asynchronous interactions
- Streaming up to or streaming down from a server
- Webflux 의존성을 추가해야한다.
더 디테일한 설명은 추후 포스팅 하겠다.
외부 환율 API 예제 코드WebClient client = WebClient.create("https://open.er-api.com"); Map<String, Map<String, Double>> res = client.get() .uri("/v6/latest") .retrieve() .bodyToMono(Map.class) .block(); System.out.println(res.get("rates").get("KRW")); //출력 : 1318.986681
retrieve() : 실제 exchange 가 실행된다(서버에 요청). 응답의 Body를 가져온다.
bodyToMono(Map.class) : 응답의 body 를 Reactor 의 Mono 객체로 바꿈
Mono : 0 ~ 1 개의 결과를 처리
Flux : 0 ~ N 개의 결과를 처리
block() : 현재의 스레드를 block 시킨 상태로.. 요청하겠다는 의미이다.
-> 이로 인해 RestTemplate 처럼 동기식으로 동작
<참고>
WebClient 는 뒤에서 별도의 쓰레드로 동작한다. 기본이 Netty Client 가 동작된다.
WebClient 는 Netty Client 의 worker thread 에서 동작한다.
block() 은 Netty Client 의 worker thread 에 비동기적으로 요청해놓고
현재의 쓰레드는 단순 block 상태로 대기하다가 응답을 받아오는 형식이다.
RestTemplate vs WebClientNon-blocking 가능 여부 Asynchronous 가능 여부 RestTemplate N N WebClient Y Y <참고>
WebClient 가 나오기 전에는 Asynchronous 를 지원하기 위해
지금은 Deprecated 된 AsyncRestTemplate 이 있었다..
3. Http Interface
Spring 6 에서 최초로 추가 되었다.
마치 Spring Data Jpa 의 JpaRepository 를 상속받아 인터페이스 만으로
repository를 사용할 수 있는 방식과 유사하다.
@HttpExchange 어노테이션이 적용되어 있는 메서드를 가진 자바 인터페이스를
Http Service 로 만들어준다.
즉, 해당 인터페이스를 구현은 따로할 필요 없으며 Spring Framework 가
exchange를 수행할 수 있는 해당 인터페이스를 구현한 프록시를 생성해준다.
바로 환율 예제 코드로 알아보자.interface ErApi { @GetExchange("/v6/latest") Map getLatest(); } @Bean ErApi erApi() { WebClient client = WebClient.create("https://open.er-api.com"); HttpServiceProxyFactory httpServiceProxyFactory = HttpServiceProxyFactory .builder(WebClientAdapter.forClient(client)) .build(); return httpServiceProxyFactory.createClient(ErApi.class); } void Caller(ErApi api) { Map<String, Map<String, Double>> res = api.getLatest(); System.out.println(res.get("rates").get("KRW")); //출력 : 1318.986681 }
사용하는 입장(Caller)에서 보면 굉장히 직관적이고 추상적이다.
따라서 확장성이 상당하다고 볼 수 있다. (DIP, OCP 관점)
(Rest 를 쓰는지.. DB에 접근하는지.. 모르겠고 ~ 받아와 ~)
<참고>
Client 를 생성해주는 작업도 어노테이션으로 추후 전환 될 가능성이 보인다고 한다.. (토비님..)
WebClient 를 사용하여 WebFlux 의 의존성이 필요하다.
Reference
https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#spring-integration
https://youtu.be/Kb37Q5GCyZs'Spring > Client' 카테고리의 다른 글
Spring Cloud OpenFeign, Synchronization (0) 2023.06.17 다음글이전글이전 글이 없습니다.댓글