Spring Web Reactive | 2. WebClient | 2.8. Synchronous Use

WebClient는 결과 마지막으로 차단하여, 동기화 스타일로 사용할 수 있다.

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())
    }

위는 단순한 예이다. 많은 원격 호출을 만든 리액티브 파이프 라인을 정리하는 다른 패턴과 연산자가 많이 있다.

FluxMono에서는 Spring MVC 또는 Spring WebFlux 컨트롤러를 차단할 필요가 없다. 컨트롤러 메소드에서 결과의 리액티브 형을 돌려 줄뿐이다. 같은 원칙이 Kotlin 코루틴과 Spring WebFlux에도 적용된다. 컨트롤러 메소드에서 중단 기능을 사용하거나 Flow를 돌려 줄뿐이다.




최종 수정 : 2021-04-12