I'm having the following simplified handler function (Spring WebFlux and the functional API using Kotlin). However, I need a hint how to detect an empty Flux and then use noContent() for 404, when the Flux is empty.
fun findByLastname(request: ServerRequest): Mono<ServerResponse> {
val lastnameOpt = request.queryParam("lastname")
val customerFlux = if (lastnameOpt.isPresent) {
service.findByLastname(lastnameOpt.get())
} else {
service.findAll()
}
// How can I detect an empty Flux and then invoke noContent() ?
return ok().body(customerFlux, Customer::class.java)
}
From a Mono
:
return customerMono
.flatMap(c -> ok().body(BodyInserters.fromObject(c)))
.switchIfEmpty(notFound().build());
From a Flux
:
return customerFlux
.collectList()
.flatMap(l -> {
if(l.isEmpty()) {
return notFound().build();
}
else {
return ok().body(BodyInserters.fromObject(l)));
}
});
Note that collectList
buffers data in memory, so this might not be the best choice for big lists. There might be a better way to solve this.
In addition to the solution of Brian, if you are not want to do an empty check of the list all the time, you could create a extension function:
fun <R> Flux<R>.collectListOrEmpty(): Mono<List<R>> = this.collectList().flatMap {
val result = if (it.isEmpty()) {
Mono.empty()
} else {
Mono.just(it)
}
result
}
And call it like you do it for the Mono:
return customerFlux().collectListOrEmpty()
.switchIfEmpty(notFound().build())
.flatMap(c -> ok().body(BodyInserters.fromObject(c)))
Use Flux.hasElements() : Mono<Boolean>
function:
return customerFlux.hasElements()
.flatMap {
if (it) ok().body(customerFlux)
else noContent().build()
}
I'm not sure why no one is talking about using the hasElements() function of Flux.java which would return a Mono.