1
votes

Say you have some fluxes and monos

val people: Flux<Person> = repo.getPeople()
val peopleCount: Mono<Int> = people.count()

and from e.g. a WebFlux controller you return a Mono<Response>:

data class Response(
    val people: List<People>,
    val personCount: Int
)

Where is the appropriate place in an application to resolve the flux and the mono to a List and Int respectively? Do you just block() everything? Is there a way to get the framework to resolve everything?

EDIT: I guess my main confusion is all the tutorials I've seen the fields inside the response object are not in fact reactive, so it seems like I need to resolve everything before returning the object from the controller. If the response object looked like this it would make more sense to me

data class Response(
    val people: Flux<People>,
    val personCount: Mono<Int>
)
1
I don't think there is ever a place to block the publishers in the controller or services, because it will lead to an exception, because you are not reactive anymore. You can return a Mono or Flux from the controller methods just fine and have it resolved by the framework. The same applies for the error handling. If your Mono/ Flux contain errors, this will also be tackled for you. - thinkgruen

1 Answers

4
votes

You can only block if you're using reactor within the servlet world, even then you can pass back the Mono/Flux and it'll be an async request.

Given you example, something like,

return repo.getPeople().collectList().map( people -> new response(peoples, people.count())

Which ends up as a Mono<Response> on which the framework will subscribe to.

You need to use the operators on the Mono/Flux and not block the reactive chain. I recommend checking out the Reactor java doc. There's great diagrams on each operator to give a visual view of what the operator is doing.