Returning list of elements with Spring Webflux
Asked Answered
P

1

6

I'am trying to create a simple example of a CRUD with Spring Webflux, but I'am getting stucked in some concepts.

I know that I can return a Flux in my controller request mapping method. But sometimes I would like to return a 404 status, so I can handle in the front-end somehow.

I found a example in the official documentation to use the ServerResponse object:

        public Mono<ServerResponse> listPeople(ServerRequest request) { 
                Flux<Person> people = repository.allPeople();
                return ServerResponse.ok().contentType(APPLICATION_JSON).body(people, Person.class);
        }

As you can see, even when the return is a list (Flux) o persons, the ServerResponse.ok.body creates a Mono.

So my question: Is that the way it is? In other words, it does not matter if I have a Flux, does Spring always return a Mono of ServerResponse (or other similar class)?

For my 404 status I could use something like

.switchIfEmpty(ServerResponse.notFound().build());

But I was thinking in something more streaming way. That I could handle the list of objects element by element, for instance.

Perrotta answered 30/5, 2017 at 14:44 Comment(8)
The ServerResponse is always a single element, hence a mono, what is returned inside that ServerResponse can be a flux and that is also what should happen.Cowpoke
@M.Deinum, thanks for your answer. But I'm not getting how to return some http status. Every example uses @GetMapping("/person") Flux<Person> list() { return this.repository.findAll(); } and not with the usual ResponseEntity object, that could contain a status.Perrotta
@IgorVeloso your latest comment suggest you're using WebFlux annotation model, but your question suggests the functional one. Could you edit your question to explain what you're trying to achieve?Endurable
@BrianClozel, that´s the real problem, In my question, I used the example in the official Spring doc, but I want to return a Http Status (let´s say 404). In my comment I´ve just written another example I had found on web, but without the http status either. Sorry if I'am not being clear about it, but as I've said, maybe I am stucked in some core concepts.Perrotta
@IgorVeloso Are you trying to return Flux<ResponseEntity<Person>>?Seaddon
Yes @SukhpalSingh, and that ResponseEntity with just a 404.Perrotta
I think the getAll can return a general Flux<>, and define an exception and throw the exception as you needed, and handle the exception and set status code.Languedoc
Have to agree with @Igor that all of the annotated controller examples I've found of a "getAll" web service method implementation either return a simple Flux and ignore error conditions (for example, directly passing on a MongoDB .findall()) or layer on ResponseEntity and sometimes ResponseWrapper with little explanation. I just want one example that shows a real error-handling implementation that Spring would recommend. What is the best practice here?Woollyheaded
B
3

I think you need the function collectList() and flatMap(). like this:

public Mono<ServerResponse> listPeople(ServerRequest request) { 
                Flux<Person> people = repository.allPeople();
                return people.collectList().flatMap(p->
                    p.size() < 1 ?
                        ServerResponse.status(404).build()
                       :ServerResponse.ok().contentType(APPLICATION_JSON).body(fromObject(p))
                ); 
        }
Baleen answered 11/9, 2019 at 11:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.