86 lines
2.4 KiB
Plaintext
86 lines
2.4 KiB
Plaintext
[[webflux-client-synchronous]]
|
|
= Synchronous Use
|
|
|
|
`WebClient` can be used in synchronous style by blocking at the end for the result:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
|
.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();
|
|
----
|
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
|
.Kotlin
|
|
----
|
|
val person = runBlocking {
|
|
client.get().uri("/person/{id}", i).retrieve()
|
|
.awaitBody<Person>()
|
|
}
|
|
|
|
val persons = runBlocking {
|
|
client.get().uri("/persons").retrieve()
|
|
.bodyToFlow<Person>()
|
|
.toList()
|
|
}
|
|
----
|
|
|
|
However if multiple calls need to be made, it's more efficient to avoid blocking on each
|
|
response individually, and instead wait for the combined result:
|
|
|
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
|
.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();
|
|
----
|
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
|
.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())
|
|
}
|
|
----
|
|
|
|
The above is merely one example. There are lots of other patterns and operators for putting
|
|
together a reactive pipeline that makes many remote calls, potentially some nested,
|
|
interdependent, without ever blocking until the end.
|
|
|
|
[NOTE]
|
|
====
|
|
With `Flux` or `Mono`, you should never have to block in a Spring MVC or Spring WebFlux controller.
|
|
Simply return the resulting reactive type from the controller method. The same principle apply to
|
|
Kotlin Coroutines and Spring WebFlux, just use suspending function or return `Flow` in your
|
|
controller method .
|
|
====
|
|
|
|
|
|
|
|
|