web-dev-qa-db-ja.com

WebFlux機能:空のFluxを検出して404を返す方法は?

私は次の単純化されたハンドラー関数(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)
}
7

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はメモリ内のデータをバッファリングするため、これは大きなリストには最適な選択ではない可能性があることに注意してください。これを解決するより良い方法があるかもしれません。

19
Brian Clozel

ブライアンの解決策に加えて、常にリストの空のチェックを行いたくない場合は、拡張関数を作成できます。

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)))
4
zennon

Flux.hasElements() : Mono<Boolean>関数を使用します。

return customerFlux.hasElements()
                   .flatMap {
                     if (it) ok().body(customerFlux)
                     else noContent().build()
                   }
3
RJ.Hwang

Monoを返すFlux.JavaのhasElements()関数の使用について誰も話していなかった理由がわかりません。

3
ayush prashar