2017-08-27 1 views
0

Ich habe die folgende vereinfachte Handler-Funktion (Spring WebFlux und die funktionale API mit Kotlin). Ich brauche jedoch einen Hinweis, wie man ein leeres Flux erkennt und dann noContent() für 404 verwendet, wenn das Flux leer ist.WebFlux funktional: Wie erkennt man einen leeren Flux und kehrt 404 zurück?

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) 
} 

Antwort

4

Von einem Mono:

return customerMono 
      .flatMap(c -> ok().body(BodyInserters.fromObject(c))) 
      .switchIfEmpty(notFound().build()); 

Aus Flux:

return customerFlux 
      .collectList() 
      .flatMap(l -> { 
       if(l.isEmpty()) { 
       return notFound().build(); 

       } 
       else { 
       return ok().body(BodyInserters.fromObject(l))); 
       } 
      }); 

Beachten Sie, dass collectList Puffer Daten im Speicher, so dass dies nicht die beste Wahl für große Listen sein könnten. Es könnte einen besseren Weg geben, dies zu lösen.

fun <R> Flux<R>.collectListOrEmpty(): Mono<List<R>> = this.collectList().flatMap { 
     val result = if (it.isEmpty()) { 
      Mono.empty() 
     } else { 
      Mono.just(it) 
     } 
     result 
    } 
es

Und nennen, wie Sie es tun:

+0

die modifizierte Variante funktioniert auch nicht. 'customerFlux.collectList()' führt zu einem Mono, das eine leere Liste enthält, wenn der ursprüngliche Flux leer ist. Daher ist das Mono nicht leer (weil es eine leere Liste enthält) und ok() wird aufgerufen. –

+1

Lösung gefunden. Innerhalb von 'flatMap()' wird eine if-Anweisung benötigt: 'if (l.isEmpty()) notFound() ... else ok() ...' Dann ist 'switchIfEmpty (...)' hier veraltet. –

+0

Ah schön, danke! –

1

Neben der Lösung von Brian, wenn Sie nicht eine leere Überprüfung der Liste die ganze Zeit tun wollen, können Sie eine Erweiterungsfunktion erstellen für das Mono:

return customerFlux().collectListOrEmpty() 
        .switchIfEmpty(notFound().build()) 
        .flatMap(c -> ok().body(BodyInserters.fromObject(c)))