私は次の単純化されたハンドラー関数(Spring WebFluxおよびKotlinを使用した関数型API)を持っています。ただし、空のFluxを検出し、Fluxが空のときに404に対してnoContent()を使用する方法のヒントが必要です。
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)
}
Mono
から:
return customerMono
.flatMap(c -> ok().body(BodyInserters.fromObject(c)))
.switchIfEmpty(notFound().build());
Flux
から:
return customerFlux
.collectList()
.flatMap(l -> {
if(l.isEmpty()) {
return notFound().build();
}
else {
return ok().body(BodyInserters.fromObject(l)));
}
});
collectList
はメモリ内のデータをバッファリングするため、これは大きなリストには最適な選択ではない可能性があることに注意してください。これを解決するより良い方法があるかもしれません。
ブライアンの解決策に加えて、常にリストの空のチェックを行いたくない場合は、拡張関数を作成できます。
fun <R> Flux<R>.collectListOrEmpty(): Mono<List<R>> = this.collectList().flatMap {
val result = if (it.isEmpty()) {
Mono.empty()
} else {
Mono.just(it)
}
result
}
Monoの場合と同じように呼び出します。
return customerFlux().collectListOrEmpty()
.switchIfEmpty(notFound().build())
.flatMap(c -> ok().body(BodyInserters.fromObject(c)))
Flux.hasElements() : Mono<Boolean>
関数を使用します。
return customerFlux.hasElements()
.flatMap {
if (it) ok().body(customerFlux)
else noContent().build()
}
Monoを返すFlux.JavaのhasElements()関数の使用について誰も話していなかった理由がわかりません。