Search code examples
javamonoreactive-programmingspring-webfluxproject-reactor

How to convert Mono object to other Mono object in Spring Webflux


I have a class like this

public class Person {
      private String name;
      private String age;
      private Boolean student;
      ...
      //
      getters and setters
}
public class PersonDto {
      private List<Person> persons
      private Person president
      //
      getters and setters
}

and get data to webclient from external API

--- omitted ---
final Mono<PersonDto> personDto = wrapperWebClient.getPersonDto(uriComponents, params, PersonDto.class);
Mono<StudentDto> studentDto = convert(personDto);
--- omitted ---

and I want to transform data Mono DTO like below.

public class Student {
      // no constructors 
      private String name;
      private String age;
      private Boolean student;
      ...
      //
      getters and setters
}
public class StudentDto {
      private List<Student> students;
      private Student represent;
      ...
      //
      getters and setters
}

it's my try

--- omitted ---
private Mono<StudentDto> convert(Mono<PersonDto> personDto) {
      StudentDto studentDto = new StudentDto();
      personDto.map(
          persons -> {
              studentDto.setStudents(
                      persons.getPersons()
                       .stream().filter(person -> person.isStudent())
                       .collect(toList())
              );
              studentDto.setRepresent(
                      persons.getRepresent().isStudent()
              );
          }
      )
      return ???;
} 

My approach seems to be synchronous.


Solution

  • Just return Mono with map

    private Mono<StudentDto> convert(Mono<PersonDto> personDto) {
          return personDto.map(
              persons -> {
                  StudentDto studentDto = new StudentDto();
                  studentDto.setStudents(
                          persons.getPersons()
                           .stream().filter(person -> person.isStudent())
                           .collect(toList())
                  );
                  studentDto.setRepresent(
                          persons.getRepresent().isStudent()
                  );
              }
          );
    } 
    

    The main difference between map and flatMap is synchronicity.

    If you want handle another asynchronous one, use flatMap.

    Or, if you just want to reformat the output of the Mono/Flux, use map.