2.6. Synchronous Use
WebClient
는 마지막에 결과를 블로킹하여 동기식(synchronous) 스타일로 사용할 수 있다:
Java:
Person person = client.get().uri("/person/{id}", i).retrieve()
.bodyToMono(Person.class)
.block();
List<Person> persons = client.get().uri("/persons").retrieve()
.bodyToFlux(Person.class)
.collectList()
.block();
Kotlin:
val person = runBlocking {
client.get().uri("/person/{id}", i).retrieve()
.awaitBody<Person>()
}
val persons = runBlocking {
client.get().uri("/persons").retrieve()
.bodyToFlow<Person>()
.toList()
}
하지만 여러 번의 호출이 필요한 경우에는 각 응답을 개별적으로 블로킹하지 않고 결합된 전체 결과를 기다리는 것이 더 효율적이다:
Java:
Mono<Person> personMono = client.get().uri("/person/{id}", personId)
.retrieve().bodyToMono(Person.class);
Mono<List<Hobby>> hobbiesMono = client.get().uri("/person/{id}/hobbies", personId)
.retrieve().bodyToFlux(Hobby.class).collectList();
Map<String, Object> data = Mono.zip(personMono, hobbiesMono, (person, hobbies) -> {
Map<String, String> map = new LinkedHashMap<>();
map.put("person", person);
map.put("hobbies", hobbies);
return map;
})
.block();
Kotlin:
val data = runBlocking {
val personDeferred = async {
client.get().uri("/person/{id}", personId)
.retrieve().awaitBody<Person>()
}
val hobbiesDeferred = async {
client.get().uri("/person/{id}/hobbies", personId)
.retrieve().bodyToFlow<Hobby>().toList()
}
mapOf("person" to personDeferred.await(), "hobbies" to hobbiesDeferred.await())
}
위의 코드는 단지 예시에 불과하다. 대량 원격 호출, 일부 중첩되고 상호 의존적이면서 호출이 끝날 때까지 블로킹하지 않는 리액티브 파이프라인을 만드는 수많은 패턴과 연산자가 있다.
Flux
또는Mono
를 사용하면, 스프링 MVC 또는 스프링 웹플럭스 컨트롤러에서 차단할 필요가 없다. 단지 컨트롤러 메서드에서 리액티브 타입을 리턴하면 된다. 코틀린 코루틴과 스프링 웹플럭스에서도 동일한 원칙이 적용된다. 컨트롤러 함수에서 일시중지(suspend) 함수를 사용하거나Flow
를 반환하면 된다.
목차 가이드