Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly wrap a Flux inside a Mono object

I have a web-service which returns student and enrolled class details.

{
  "name": "student-name",
  "classes": [
    {
      "className": "reactor-101",
      "day": "Tuesday"
    },
    {
      "className": "reactor-102",
      "day": "Friday"
    }
  ]
}

The DTO for this class is as below:

public class Student {
        private String name;
        private Flux<StudentClass> classes;
        @Data
        @AllArgsConstructor
        @JsonInclude(JsonInclude.Include.NON_DEFAULT)
        public static class StudentClass {
            private String className;
            private String day;
        }
    }

The main REST controller logic to fetch the student is as follows:

Flux<StudentClass> studentClassFlux = studentClassRepository.getStudentClass(studentName);

return Mono.just(new Student(studentName, studentClassFlux));

The problem with this is, I get the following output after making the REST call:

{
  "name": "student-name",
  "classes": {
    "prefetch": 32,
    "scanAvailable": true
  }
}

I can achieve the desired output by blocking on the flux request to get completed and then convert the output to list.

List<StudentClass> studentClassList = studentClassRepository.getStudentClass(studentName)..toStream().collect(Collectors.toList());
return Mono.just(new Student(studentName, studentClassList)); // Change the Student#classes from flux to list

I am new to reactive-programming. What is the correct way of using the Flux & Mono here to get the desired output?

like image 895
K. Bhandari Avatar asked Oct 29 '22 02:10

K. Bhandari


1 Answers

Reactive types aren't meant to be serialized when wrapped in each other. In that particular case, you probably want your Student object to contain a List<StudentClass>. You can achieve that like this:

public Mono<Student> findStudent(String studentName) {

    return studentClassRepository
             .getStudentClass(studentName)
             .collectList()
             .map(studentClasses -> new Student(studentName, studentClasses));
}
like image 114
Brian Clozel Avatar answered Jan 02 '23 19:01

Brian Clozel