Pierre-Yves Nicolas
Pierre-Yves Nicolas

Reputation: 13

Spring webflux - multi Mono

I do not know or ask this question except here, if it's not the place I apologize.

I am currently working on an application using spring webflux and I have a problem with the use of Mono and Flux.

Here I have a REST request that comes with a simple bean that contains attributes including a list. This list is iterated to use a responsive mongo call that returns a Mono (findOne). But I do not think I've found the right way to do it:

@PostMapping
@RequestMapping("/check")
public Mono<ContactCheckResponse> check(@RequestBody List<ContactCheckRequest> list) {
    final ContactCheckResponse response = new ContactCheckResponse();
    response.setRsnCode("00");
    response.setRspnCode("0000");
    LOG.debug("o--> person - check {} items", list.size());

    final List<ContactCheckResponse.Contact> contacts = new ArrayList<>();
    response.setContacts(contacts);

    return Mono.fromCallable(() -> {
        list.stream().forEach( c -> {
            Boolean exists = contactRespository.findOneByThumbprint(c.getIdentifiant()).block() != null;
            ContactCheckResponse.Contact responseContact = new ContactCheckResponse.Contact();
            responseContact.setExist(exists);
            responseContact.setIdentifiant(c.getIdentifiant());
            responseContact.setRsnCode("00");
            responseContact.setRspnCode("0000");
            response.getContacts().add(responseContact);
        });
        return response;
    });
}

the fact of having to make a block does not seem to me in the idea "reactive" but I did not find how to do otherwise.

Could someone help me find the best way to do this task?

Thank you

Upvotes: 1

Views: 1097

Answers (1)

a better oliver
a better oliver

Reputation: 26848

Something along these lines:

return Flux.fromIterable(list)
  .flatMap(c -> contactRespository.findOneByThumbprint(c.getIdentifiant())
                  .map(r -> r != null)
                  .map(exists -> {
                         ContactCheckResponse.Contact responseContact = new ContactCheckResponse.Contact();
                         ...
                         return responseContact;
                      })
          )
 .reduce(response, (r,c) -> {
                               response.getContacts().add(responseContact);
                               return response;
         });       

Create a Flux from the list, create a contact for each entry and reduce everything to a Mono.

Upvotes: 3

Related Questions