[20250217] webclient ๊ธฐ๋ณธ ์์๋ก ์ฌ์ฉ๋ฐฉ๋ฒ ์์๋ณด๊ธฐ!
WebClient ์์ ์ ๋ณต ๊ฐ์ด๋: ์ด๋ณด์๋ ์ดํดํ๋ ํต์ฌ ๊ฐ๋ ๊ณผ ํ์ฉ๋ฒ
WebClient๋ Spring 5๋ถํฐ ์๋กญ๊ฒ ์ถ๊ฐ๋ ๋น๋๊ธฐ ๋ฐฉ์์ HTTP ํด๋ผ์ด์ธํธ์ ๋๋ค. ๊ธฐ์กด์ RestTemplate์ ๋นํด Non-Blocking ๋ฐฉ์์ผ๋ก ๋์ํ์ฌ ๋์ ์ฑ๋ฅ์ ์ ๊ณตํ๋ฉฐ, ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์คํ์ผ์ ์ง์ํ์ฌ ์ฝ๋๋ฅผ ๊ฐ๊ฒฐํ๊ณ ์ ์ฐํ๊ฒ ์์ฑํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
1. WebClient๋?
WebClient๋ HTTP ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ์ฒ๋ฆฌํ๋ ์ญํ ์ ํฉ๋๋ค. RestTemplate์ ๋ง์ฐฌ๊ฐ์ง๋ก GET, POST, PUT, DELETE ๋ฑ ๋ค์ํ HTTP ๋ฉ์๋๋ฅผ ์ง์ํ๋ฉฐ, ๋น๋๊ธฐ ๋ฐฉ์์ผ๋ก ๋์ํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
2. WebClient ์ฌ์ฉ ๋ฐฉ๋ฒ
2.1. ์์กด์ฑ ์ถ๊ฐ
WebClient๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ Spring WebFlux ์์กด์ฑ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. Maven ํ๋ก์ ํธ์ ๊ฒฝ์ฐ pom.xml ํ์ผ์ ๋ค์์ ์ถ๊ฐํฉ๋๋ค.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Gradle ํ๋ก์ ํธ์ ๊ฒฝ์ฐ build.gradle ํ์ผ์ ๋ค์์ ์ถ๊ฐํฉ๋๋ค.
implementation 'org.springframework.boot:spring-boot-starter-webflux'
2.2. WebClient ์ธ์คํด์ค ์์ฑ
WebClient๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋จผ์ WebClient ์ธ์คํด์ค๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด WebClient.create() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
WebClient webClient = WebClient.create();
2.3. HTTP ์์ฒญ ๋ณด๋ด๊ธฐ
WebClient ์ธ์คํด์ค๋ฅผ ์์ฑํ ํ์๋ ๋ค์ํ HTTP ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ฒญ์ ๋ณด๋ผ ์ ์์ต๋๋ค. ๋ค์์ GET ์์ฒญ์ ๋ณด๋ด๋ ์์์ ๋๋ค.
Mono<String> response = webClient.get()
.uri("https://example.com/api/data")
.retrieve()
.bodyToMono(String.class);
์ ์ฝ๋๋ https://example.com/api/data URL์ GET ์์ฒญ์ ๋ณด๋ด๊ณ , ์๋ต ๊ฒฐ๊ณผ๋ฅผ String ํ์ ์ผ๋ก Mono์ ๋ด์ ๋ฐํํฉ๋๋ค. Mono๋ ๋น๋๊ธฐ ์คํธ๋ฆผ์ ๋ํ๋ด๋ ๊ฐ์ฒด๋ก, ์๋ต์ด ๋์ฐฉํ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ค๋ฅธ ์์ ์ ์ํํ ์ ์์ต๋๋ค.
2.4. ์๋ต ์ฒ๋ฆฌ
Mono ๋๋ Flux ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ์๋ต ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ๋ค์์ Mono ๊ฐ์ฒด์์ ์๋ต ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ค๋ ์์์ ๋๋ค.
response.subscribe(data -> {
System.out.println("์๋ต ๊ฒฐ๊ณผ: " + data);
});
์ ์ฝ๋๋ Mono ๊ฐ์ฒด์ subscribe() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์๋ต ๊ฒฐ๊ณผ๋ฅผ ๊ตฌ๋ ํ๊ณ , ์๋ต์ด ๋์ฐฉํ๋ฉด data ๋ณ์์ ๋ด์ ์ฒ๋ฆฌํฉ๋๋ค.
3. WebClient ๊ธฐ๋ณธ ์์
๋ค์์ WebClient๋ฅผ ์ฌ์ฉํ์ฌ GET, POST ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ์ฒ๋ฆฌํ๋ ๊ฐ๋จํ ์์ ์ ๋๋ค.
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
public class WebClientExample {
public static void main(String[] args) {
WebClient webClient = WebClient.create();
// GET ์์ฒญ
Mono<String> getResponse = webClient.get()
.uri("https://jsonplaceholder.typicode.com/todos/1")
.retrieve()
.bodyToMono(String.class);
getResponse.subscribe(data -> System.out.println("GET ์๋ต: " + data));
// POST ์์ฒญ
Mono<String> postResponse = webClient.post()
.uri("https://jsonplaceholder.typicode.com/todos")
.bodyValue("{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}")
.retrieve()
.bodyToMono(String.class);
postResponse.subscribe(data -> System.out.println("POST ์๋ต: " + data));
}
}
์ ์ฝ๋๋ https://jsonplaceholder.typicode.com API๋ฅผ ์ฌ์ฉํ์ฌ GET ์์ฒญ๊ณผ POST ์์ฒญ์ ๋ณด๋ด๊ณ , ๊ฐ๊ฐ์ ์๋ต ๊ฒฐ๊ณผ๋ฅผ ์ฝ์์ ์ถ๋ ฅํฉ๋๋ค.
4. WebClient ์ถ๊ฐ ๊ธฐ๋ฅ
WebClient๋ ๋ค์๊ณผ ๊ฐ์ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- ํค๋ ์ค์ : ์์ฒญ์ ํ์ํ ํค๋๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
- ์ฟ ํค ์ค์ : ์์ฒญ์ ํ์ํ ์ฟ ํค๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
- ํ์์์ ์ค์ : ์์ฒญ์ ๋ํ ํ์์์ ์๊ฐ์ ์ค์ ํ ์ ์์ต๋๋ค.
- ์๋ฌ ์ฒ๋ฆฌ: ์๋ต ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.