created at 2025-01-28
Table of contents
- sync/blocking 하는 restTemplate deprecated 하고 async/non-blocking 하는 webClient 로 완벽이전 하려고 했으나 중간다리가 필요함
sync/blocking 하는 restTemplate deprecated 하고 async/non-blocking 하는 webClient 로 완벽이전 하려고 했으나 중간다리가 필요함
아래의 discussion 에서 restClient 가 왜 나왔는지 discussion 이 있어서 정리해봄.
Reference: https://github.com/spring-projects/spring-framework/issues/29552
- Spring 5.0 나오면서 async/non-blocking 풀 장착한 NIO 리엑터 기반의 WebClient 가 나옴. 그리고 Spring 6.1 에 restTemplate 에서 webClient 로 완벽이전 할려고함.
- 이것의 전제가 Java Project Loom 가상 스레드 기반의 async/non-blocking 풀 지원임. 그런데 이게 어떤 구조로 병렬성을 지원할 지 모름. Spring 팀에서 보기에 Project Loom 이 정착할려면 꽤 많은 시간이 소모될 것으로 보인다고 판단. DB async 도 지원해야되고 따라서 restTemplate 를 deprecated 시키기엔 아직 이르다고 판단함. + async/non-blocking 을 사용할 필요가 없는 경우가 있는데 webClient 는 이를 강요하는 듯한 인터페이스임.
- 그래서 restTemplate 의 쉬운 blocking 인터페이스를 default 로 계속 사용하되, WebClient 를 간접 사용할 수 있게끔 하려고 함. 이것이 restClient 임. fully async/non-blocking 과 sync/blocking 의 중간 연결다리 느낌.
RestClient 의 Rest prefix 는 RESTful API 를 지칭하는 것이 아니라, restTemplate 의 계보를 잇는다는 느낌으로 rest prefix 를 붙였다고 함.
사실 restTemplate 또한 restful API 를 지칭하는게 아니긴함. 그냥 이름이 그렇게 지어진 것일 뿐. poutsma 뿐만 아니라 다른 사람들도 이 잘못 지어진 이름에 신경이 쓰인다고 함. 아마 되돌아가면 rest 라는 prefix 를 없애버리지 않을까 생각함.
interceptor, exception, error handler, retry, … 등등 restTemplate 에서 사용하던 기능들을 restClient 에서도 사용할 수 있음. 그리고 되게 쉽게 restTemplate 에서 restClient 로 마이그레이션 할 수 있음.
@Bean(name = ["paymentRestTemplate"])
fun paymentRestTemplate(): RestTemplate {
val requestFactory = SimpleClientHttpRequestFactory()
requestFactory.setConnectTimeout(3 * 1000)
requestFactory.setReadTimeout(30 * 1000)
return RestTemplateBuilder()
.setConnectTimeout(Duration.ofMillis(3 * 1000))
.setReadTimeout(Duration.ofMillis(30 * 1000))
.requestFactory { _ ->
BufferingClientHttpRequestFactory(requestFactory)
}
.interceptors(consoleLogApiCallInterceptor)
.build()
}
@Bean(name = ["paymentRestClient"])
fun paymentRestClient(): RestClient {
val requestFactory = SimpleClientHttpRequestFactory()
requestFactory.setConnectTimeout(3 * 1000)
requestFactory.setReadTimeout(30 * 1000)
return RestClient.builder()
.requestFactory(requestFactory)
.requestInterceptor(restClientConsoleLogApiCallInterceptor)
.messageConverters { converters ->
converters.removeIf { it is MappingJackson2HttpMessageConverter }
converters.add(customJacksonMessageConverter)
}
.build()
}
보면 converter, interceptor, requestFactory 등등 restTemplate 에서 사용하던 것들을 restClient 에서도 사용할 수 있음. 그리고 restClient 는 restTemplate 를 상속받아서 만들어졌기 때문에 restTemplate 에서 사용하던 것들을 그대로 사용할 수 있음.
With RestClient we are introducing a HTTP client that offers an API similar to WebClient, and that uses the message converters, request factories, interceptors, and other underlying components of RestTemplate.
reference : https://spring.io/blog/2023/07/13/new-in-spring-6-1-restclient
진짜 위의 래퍼에 얘네가 말한대로 restTemplate 의 request factories, interceptor, etc. 그대로 쓸 수 있으면서도 webClient 와 비슷한 async/non-blocking 간접체험 가능. 거기에 spring-boot-starter-webflux 는 필요없도록 구성했다고 함.