javaspring-webfluxproject-reactorreactorreactive-streams

How to combine a Mono and a Flux to create one object?


I want to create one object and the object is made up of a Mono and a Flux. Suppose there are 2 services getPersonalInfo and getFriendsInfo. Person needs both services to create an object. Zipping only takes the first element of friends object since there is only one personalInfo as it is Mono, but friendsInfo might have multiple friend objects in them. I want to set the friendsInfo to friend in Person.

class Person{
    String name;
    String age;
    List<Friend> friend;
}

Mono<PersonalInfo> personalInfo = personService.getPerson();// has name and age
Flux<Friend> friendsInfo = friendsService.getFriends();
// here I want to create Person object with personalInfo and friendsInfo
Flux<Person> person = Flux.zip(personalInfo, friendsInfo, (person, friend) -> new Person(person, friend));

Solution

  • From your question I assume you want to create a single person object which contains the name & age populated from your Mono<PersonalInfo>, and the friends list from your Flux<Person>.

    Your attempt is pretty close:

    Flux<Person> person = Flux.zip(Person, Friend, (person, friend) -> new Person(person, friend));
    

    In particular, the zip operator with the overload that takes two publishers & a combinator is exactly the correct thing to use here. However, a couple of things that need changing:

    So putting that together, you end up with something like:

    Mono<Person> person = Flux.zip(personalInfo, friendsInfo.collectList(), (personalInfo, friendsList) -> new Person(personalInfo, friendsList));
    

    ...which should give you what you're after.