Reputation: 13
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
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