francesco foresti
francesco foresti

Reputation: 2043

How to combine each element of a Flux with another Flux that needs an element's attribute

I have a question about Spring WebFlux and Reactor. I am trying to code a simple scenario where in a GET endpoint i return a Flux of DTOs representing entities, and each of these entities has a collection of other DTOs representing another entity. Here follow the details.

I have two entities, Person and Song, defined as follows:

@Data
public class Person {
    @Id
    private Long id;
    private String firstName;
    private String lastName;
}

@Data
public class Song {
    @Id
    private Long id;
    private String title;
    private Long authorId;
}

the entities are represented by the following DTOs:

@Data
public class SongDTO {
    private Long id;
    private String title;
    public static SongDTO from(Song s) {
        // converts Song to its dto
    }
}

@Data
public class PersonDTO {
    private Long id;
    private String firstName;
    private String lastName;
    private List<SongDTO> songs = new ArrayList<>();
    public static PersonDTO from(Person p, List<Song> songs) {
        // converts person to its dto, invokes SongDTO.from on each song 
        // and adds the result to personDTO.songs
    }
}

My services (not shown here for the sake of brevity) do return Mono and Flux. Then I have the the following RestController:

@RestController
@RequestMapping("/people")
public class PersonController {
    @Autowired PersonService people;
    @Autowired SongService songs;
    
    @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public Flux<PersonDTO> findAllPeople() {
        return people.findAll()
                .map(person -> PersonDTO.from(person, /* HERE */ new ArrayList<>()));
        // TODO: find the songs of each author reactively and put the results in personDTO.songs
    }
}

Now, my problem is: how do I

I tried to look into Reactor's documentation without success, searched other StackOverflow questions and the internet at large, but couldn't find anything, most probably because I am not really sure about how to phrase my search. Can someone please provide hints?

Thank You

Upvotes: 1

Views: 5672

Answers (1)

Martin Tarj&#225;nyi
Martin Tarj&#225;nyi

Reputation: 9937

You can use flatMap + map:

people.findAll()
      .flatMap(person -> songs.findByAuthorId(person.getId())
                              .collectList()
                              .map(songList -> PersonDTO.from(person, songList)));

Upvotes: 5

Related Questions