morenow
morenow
morenow
전체 방문자
오늘
어제
  • 분류 전체보기 (83)
    • 스프링부트와 AWS로 혼자 구현하는 웹 서비스 (5)
    • [MSA] Spring Cloud로 개발하는 마이.. (14)
    • Baekjoon Online Judge (40)
    • Programmers (11)
    • Spring Boot (7)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Open Feign
  • jwt
  • HttpExchange
  • Feign Client
  • re-distribution
  • Spring Boot
  • JWT단점
  • successHandler
  • lost update
  • copy up
  • B+ Tree
  • HTTP Interface
  • 백준20058C++
  • write skew
  • 백준 파이어스톰
  • Id Token
  • B Tree
  • Refresh Token Refresh
  • 마법사 상어와 파이어스톰
  • dirty write

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
morenow

morenow

Spring Boot

Spring의 새로운 동기식 HTTP Client, RestClient

2024. 3. 9. 17:02

RestTemplate 의 maintenance mode로 전환

Spring 에서 주로 사용했던 HTTP Client인 RestTemplate이 maintenance mode 로 들어가고, Webclient 로 대체해서 사용하길 권장한다는 것이다. 아래는 spring docs 의 한 부분이다.

NOTE:
 As of 5.0 this class is in maintenance mode, with only minor requests for changes and bugs to be accepted going forward. Please, consider using the 
org.springframework.web.reactive.client.WebClient
 which has a more modern API and supports sync, async, and streaming scenarios.

 

RestTemplate 를 모두 사용해 봤다면 알겠지만 RestTemplate 은 사용이 꽤나 불편하다. Client 클래스가 아니라 Template 클래스이기 때문이다. 이를 해결하기 위해 Webflux 위에서 동작하는 WebClient 를 개발했고, 이를 적극적으로 사용할 것을 권장했다.

 

하지만, 문제가 있었다. Webflux 위에서 동작하기 때문에 이 무거운 의존성을 포함해야 하기 때문이었다. 동기적으로만 HTTP Client 를 간단하게 사용할 사람은 의존성을 포함하는 것이 무겁게 느껴졌다.

그래서 Spring 6.1 그리고 Spring Boot 3.2 부터 새로운 HTTP Client인 RestClient가 추가되었다.

 

스프링 공식문서에서 다음과 같이 설명한다.

The Spring Framework provides the following choices for making calls to REST endpoints:
RestClient - synchronous client with a fluent API.
WebClient - non-blocking, reactive client with fluent API.
RestTemplate - synchronous client with template method API.
HTTP Interface - annotated interface with generated, dynamic proxy implementation.

모든 내용들은 스프링 공식문서에서 참고했다. https://docs.spring.io/spring-framework/reference/integration/rest-clients.html

 

REST Clients :: Spring Framework

WebClient is a non-blocking, reactive client to perform HTTP requests. It was introduced in 5.0 and offers an alternative to the RestTemplate, with support for synchronous, asynchronous, and streaming scenarios. WebClient supports the following: Non-blocki

docs.spring.io

RestClient

사용하려면, 먼저 다음과 같이 RestClient를 생성해야 한다.

RestClient restClient = RestClient.builder()
  .requestFactory(new HttpComponentsClientHttpRequestFactory())
  .messageConverters(converters -> converters.add(new MyCustomMessageConverter()))
  .baseUrl("https://example.com")
  .defaultUriVariables(Map.of("variable", "foo"))
  .defaultHeader("My-Header", "Foo")
  .requestInterceptor(myCustomInterceptor)
  .requestInitializer(myCustomInitializer)
  .build();

그 후, 이 restClient를 사용한다.

ResponseEntity<String> result = restClient.get() 
  .uri("/home") 
  .retrieve()
  .toEntity(String.class); 

System.out.println("Response status: " + result.getStatusCode()); 
System.out.println("Response headers: " + result.getHeaders()); 
System.out.println("Contents: " + result.getBody());

 

사용방법은 정말 어렵지 않다.

 

HttpExchange

HttpExchange 어노테이션은 Spring6에서 제공된 기능으로 인터페이스 기반으로 자동으로 구현해주는 기능이다. open feign 과 유사하게 간편한 방식을 Spring 에서 공식적으로 지원하지만, 이전까지는 WebClient 만을 지원해서 Webflux 를 포함해야 하는 점이 문제였다. 이제 HttpExchange가 RestClient 도 지원하므로 다음과 같이 설정하면 쉽게 사용할 수 있다.

 

아래의 코드는 다음 프로젝트에서 사용한 알라딘 오픈 API 를 통해 책 정보를 받아오는 코드이다.

https://github.com/BookitList/BookitList_backend

 

GitHub - BookitList/BookitList_backend: BookitList_backend

BookitList_backend. Contribute to BookitList/BookitList_backend development by creating an account on GitHub.

github.com

 

먼저, 인터페이스부터 만든다.

메소드에는 @GetExchange 등의 어노테이션과 baseUrl 이후의 부분을 적으면 된다. 그리고 @RequestParam과 파라미터에 들어갈 것들을 적어주면 된다.

@Component
@HttpExchange
public interface AladinComponent {

    @GetExchange("/ItemSearch.aspx")
    String findAllByQuery(@RequestParam String TTBKey, @RequestParam String Query, @RequestParam String Output, @RequestParam int Start, @RequestParam int MaxResults, @RequestParam int Version);

    @GetExchange("/ItemLookUp.aspx")
    String findByIsbn13(@RequestParam String TTBKey, @RequestParam String ItemId, @RequestParam String ItemIdType, @RequestParam String Output, @RequestParam int Version);

}

 

이제 이 인터페이스를 구현할 설정 클래스를 작성한다.

baseUrl 과 함께 RestClient를 만들고, HttpServiceProxyFactory 를 통해 위에 코딩한 인터페이스를 구현해서 스프링 빈으로 등록하면 된다.

@Configuration
public class RestClientConfig {

    @Bean
    public AladinComponent aladinService() {
        RestClient restClient = RestClient.builder()
                .baseUrl("http://www.aladin.co.kr/ttb/api")
                .build();
        RestClientAdapter adapter = RestClientAdapter.create(restClient);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();

        return factory.createClient(AladinComponent.class);
    }
}

 

이제 인터페이스에 작성한 메소드를 다음과 같이 사용하면 된다.

밑의 코드는 응답을 그대로 객체로 deserialize 하지 않고, 파싱한 후에 객체로 만들어야 하기 때문에 JSONObject 를 사용했다.

JSONObject json = new JSONObject(aladinComponent.findAllByQuery(aladinKey, keyword, "JS", start, maxResults, 20131101));

 

마지막에 소개한 이 방법이 현재 Spring 에서 사용하는 HTTP Client 방법 중 가장 좋은 방법이라고 생각된다.

RestTemplate 의 직관적이지 않은 템플릿 메소드의 단점, Open Feign 의 공식적으로 지원하지 않는 단점, WebClient 의 Webflux 를 추가해야 하는 단점을 모두 해결한 방법이다.

'Spring Boot' 카테고리의 다른 글

Auto Increment에서 Tsid로의 전환  (0) 2024.11.23
JWT 총정리 (2) - Access Token, Refresh Token  (1) 2024.03.08
JWT 총정리 (1) - JWT의 원리와 흐름  (1) 2023.10.09
Git in IntelliJ - 인텔리제이에서 Git의 모든 것 (2)  (0) 2023.02.03
Git in IntelliJ - 인텔리제이에서 Git의 모든 것 (1)  (0) 2023.01.27
    'Spring Boot' 카테고리의 다른 글
    • Auto Increment에서 Tsid로의 전환
    • JWT 총정리 (2) - Access Token, Refresh Token
    • JWT 총정리 (1) - JWT의 원리와 흐름
    • Git in IntelliJ - 인텔리제이에서 Git의 모든 것 (2)
    morenow
    morenow

    티스토리툴바