You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.5 KiB
97 lines
2.5 KiB
[[webflux-client-synchronous]] |
|
= Synchronous Use |
|
|
|
`WebClient` can be used in synchronous style by blocking at the end for the result: |
|
|
|
[tabs] |
|
====== |
|
Java:: |
|
+ |
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
|
---- |
|
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:: |
|
+ |
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] |
|
---- |
|
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: |
|
|
|
[tabs] |
|
====== |
|
Java:: |
|
+ |
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
|
---- |
|
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:: |
|
+ |
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] |
|
---- |
|
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 . |
|
==== |
|
|
|
|
|
|
|
|
|
|