Spring RestTemplate vs WebClient
๐ RestTemplate vs Webclient
RestTemplate
thread-per-request ๋ชจ๋ธ์ ๊ธฐ๋ฐํ๋ Java Servlet API๋ฅผ ์ฌ์ฉํจ.-> Synchronous & Blocking
ํด๋ผ์ด์ธํธ๊ฐ ์๋ต์ ๋ฐ์ ๋๊น์ง thread๊ฐ ๋ธ๋ญ ์ํ
์. ๋ฉ๋ชจ๋ฆฌ์ CPU cycle์ ์๋ชจํ๋ ๊ฒ์ผ๋ก ์ธํ block code์ ๋จ์ ์ด ๋ฐ์ํจ.
๊ฒฐ๊ณผ์ ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์
์ด ๋ง์ ์ค๋ ๋๋ฅผ ์์ฑํ๊ณ , ์ด๊ฒ์ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ชจ๋ ์ ์ ํ๊ฑฐ๋ ์ค๋ ๋ ํ์ ์๋ชจํ ์ ์์.
WebClient
Spring Reactive ํ๋ ์์ํฌ๊ฐ ์ ๊ณตํ๋ Asynchronous, non-blocking ๋ฐฉ์์ ์ฌ์ฉํจ.
RestTemplate์ ๊ฐ HTTP ์์ฒญ๋ง๋ค thread๋ฅผ ํธ์ถํ๊ณ , WebClient๋ HTTP ์์ฒญ๋ง๋ค "task"๋ฅผ ์์ฑํจ. Reactive ํ๋ ์์ํฌ๋ ๊ทธ task๋ค์ ํ์ ๋ฃ์๋ค๊ฐ ์ ์ ํ ์๋ต์ด ๊ฐ๋ฅํ ๋ task๋ฅผ ์คํํจ.
Reactive ํ๋ ์์ํฌ๋ event-driven ์ํคํ ์ณ๋ฅผ ์ฌ์ฉํด์ Reactive Streams API๋ฅผ ํตํด asynchronous logic์ ์ง๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํจ. ๊ฒฐ๊ณผ์ ์ผ๋ก Reacitveํ ์ ๊ทผ์ synchronous/blocking ๋ฐฉ๋ฒ๋ณด๋ค ์ ์ ์ค๋ ๋์ ์์คํ ์์์ ์ฌ์ฉํ๋ฉด์ ๋ ๋ง์ ๋ก์ง์ ์ํํ ์ ์์.
WebClient๋ Srping WebFlux ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํฌํจ๋จ. ๋ฐ๋ผ์ ๋ฐ์ํ(Mono ๋ฐ Flux)์ ์ ์ธ์ ๊ตฌ์ฑ์ผ๋ก ์ฌ์ฉํ์ฌ ๊ธฐ๋ฅ์ ์ด๊ณ ์ ์ฐฝํ API๋ฅผ ์ฌ์ฉํ์ฌ ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ์์ฑํ ์๋ ์์.
Spring5.0 ๋ฒ์ ๋ถํฐ RestTemplate์ ๋์์ผ๋ก WebClient ์ฌ์ฉ์ ๊ถ๊ณ ํจ.
WebClient์ ํน์ง
- 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
์์๋ฅผ ํตํ RestTemplate WebClient ๋น๊ต
java
@GetMapping("/slow-service-tweets")
private List<Tweet> getAllTweets() {
Thread.sleep(2000L); // delay
return Arrays.asList(
new Tweet("RestTemplate rules", "@user1"),
new Tweet("WebClient is better", "@user2"),
new Tweet("OK, both are useful", "@user1"));
}
RestTemplate๋ฅผ ์ฌ์ฉํ์ ๋
@GetMapping("/tweets-blocking")
public List<Tweet> getTweetsBlocking() {
log.info("Starting BLOCKING Controller!");
final String uri = getSlowServiceUri();
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<List<Tweet>> response = restTemplate.exchange(
uri, HttpMethod.GET, null,
new ParameterizedTypeReference<List<Tweet>>(){});
List<Tweet> result = response.getBody();
result.forEach(tweet -> log.info(tweet.toString()));
log.info("Exiting BLOCKING Controller!");
return result;
}
๊ฒฐ๊ณผ
Starting BLOCKING Controller!
Tweet(text=RestTemplate rules, username=@user1)
Tweet(text=WebClient is better, username=@user2)
Tweet(text=OK, both are useful, username=@user1)
Exiting BLOCKING Controller!
WebClient๋ฅผ ์ฌ์ฉํ์ ๋
@GetMapping(value = "/tweets-non-blocking",
produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Tweet> getTweetsNonBlocking() {
log.info("Starting NON-BLOCKING Controller!");
Flux<Tweet> tweetFlux = WebClient.create()
.get()
.uri(getSlowServiceUri())
.retrieve()
.bodyToFlux(Tweet.class);
tweetFlux.subscribe(tweet -> log.info(tweet.toString()));
log.info("Exiting NON-BLOCKING Controller!");
return tweetFlux;
}
๊ฒฐ๊ณผ
Starting NON-BLOCKING Controller!
Exiting NON-BLOCKING Controller!
Tweet(text=RestTemplate rules, username=@user1)
Tweet(text=WebClient is better, username=@user2)
Tweet(text=OK, both are useful, username=@user1)
๐ Reactive Programming์ด๋?
The introduction to Reactive Programming you've been missing · GitHub
๐ Reactive Stream
์๋ 4๊ฐ์ง Component๋ก ๊ตฌ์ฑ๋จ
- Publisher
- Subscriber
- Subscription
- Processor
Publisher๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์ฐํ๊ณ , Subscriber๊ฐ ๋ฑ๋ก๋๊ธฐ ์ ๊น์ง ์๋ฌด๋ฐ ์ผ๋ ํ์ง ์์. Publisher๋ Subscriber๊ฐ ๋ฑ๋ก๋๋ ์์ ๋ถํฐ ๋ฐ์ดํฐ๋ฅผ pushํจ.
Spring Webflux์์ ์ฌ์ฉํ๋ reactive libaray๊ฐ Reactor์ด๊ณ Reactor๊ฐ Reactive Streams์ ๊ตฌํ์ฒด!
๋ฆฌ์กํฐ๋ Mono์ Flux 2๊ฐ์ง ๋ฐ์ดํฐ ํ์ ์ผ๋ก ์คํธ๋ฆผ์ ์ ์ํจ.
WebFlux์์๋ ๋ชจ๋ ์๋ต์ Mono ํน์ Flux์ ๋ด์์ ๋ฐํํด์ฃผ์ด์ผ ํจ.
๐ Mono์ Flux
Flux์ Mono๋ Reactor ๊ฐ์ฒด์ด๋ฉฐ, ์ฐจ์ด์ ์ ๋ฐํํ๋ ๋ฐ์ดํฐ ๊ฐฏ์
- Flux: 0~N๊ฐ์ ๋ฐ์ดํฐ ์ ๋ฌ
- Mono: 0~1๊ฐ์ ๋ฐ์ดํฐ ์ ๋ฌ
Reactor์์ ์ ๊ณตํ๋ ๋ค์ํ operator๋ค์ ์กฐํฉ์ ํตํด ์คํธ๋ฆผ์ ํํํ ์ ์์.
operator๋ ๋งค์ฐ ๋ง์ผ๋ฏ๋ก ๋์ ๋ฐ๋ผ ์ ์ ํ operator๋ฅผ ์ ์ฉํด์ผํจ.
Spring WebClient vs. RestTemplate | Baeldung
[spring] WebFlux๋ + Reactor ๊ฐ์ฒด๋ (Mono<> ์ Flux<>) (tistory.com)
[Spring WebFlux] 0. ๋ฆฌ์กํฐ๋ธ ํ๋ก๊ทธ๋๋ฐ์ ์๊ฐ — ๐ HOON DEVLog (tistory.com)
https://ddoriya.tistory.com/entry/RestTemplate-VS-WebClient
[Spring] WebFlux์ ๊ฐ๋ / Spring MVC์ ๊ฐ๋จ๋น๊ต (tistory.com)