PARO
PARO

Reputation: 155

Iterating through Flux <T> and fetching data with Webclient

I am trying to fetch the data from another microservice. Suppose you have three microservices: State, School and Student. You get the Flux< School> via stateId from SchoolRepository and for each School you are calling Student microservice via webclient which returns Flux< Students> and setting it to Flux< School>. Shortly, what I am trying to do is:

public Flux<School> getBySchool(Long stateId){

        Flux<School> schoolList=schoolRepository.findByStateId(stateId);
        //And for each school I want to do this
                Flux<Student> studentsfound=webClient.get().uri("bla bla bla"+school.getSchoolId).exchange().flatMapMany(response->response.bodyToFlux(Student.class));
                //I have a List<Student> entity in School domain, so I want Flux<Student> --> List<Student> and add it to School. Something like school.setStudentList(studentListReturned).
        //And then return Flux<Stundent>
}

How can I iterate through Flux< School > , and after getting Flux< Student > how can I add it to the appropriate Flux< School> ? Thank you in advance.

UPDATE

SOLUTION

Many thanks to @K.Nicholas. I was able to solve the problem as below, but more elegant solutions are welcome. And I'm subscribing to schoolList in my controller as I have to return Flux< School> from service layer to controller layer.

public Flux<School> getBySchoolWithStudents(Long stateId) {
    Flux<School> schoolList = schoolRepository.findByStateId(stateId);
    return schoolList.flatMap(school -> {
        Flux<Student> studentFlux = webClientBuilder.build().get().uri(REQUEST_URI + school.getSchoolId()).exchange().flatMapMany(response -> response.bodyToFlux(Student.class));
        return studentFlux.collectList().map(list -> {
            school.setStudentList(list);
            return school;
        });
    });
}

Upvotes: 0

Views: 2850

Answers (1)

K.Nicholas
K.Nicholas

Reputation: 11561

EDIT: Second attempt. So, nothing particularly special that I can see. Uses the collectList method and assigns it in a map function. The map function returns the school object that is in scope. I had to do a bit of debugging to ensure my classes supported serialization/deserialization properly.

    WebClient.create().get().uri(URI.create("http://localhost:8082/ss/school?state=CA"))
    .accept(MediaType.APPLICATION_JSON)
    .exchange()
    .flatMapMany(cr->cr.bodyToFlux(School.class))
    .flatMap(school->{
        return WebClient.create().get().uri(URI.create("http://localhost:8081/ss/student?school="+school.getName()))
        .accept(MediaType.APPLICATION_JSON)
        .exchange()
        .flatMapMany(crs->crs.bodyToFlux(Student.class))
        .collectList()
        .map(sl->{
            school.setStudents(sl);
            return school;
        });
    })
    .subscribe(System.out::println);

Upvotes: 1

Related Questions