vv01
vv01

Reputation: 91

Spring Webflux: efficiently using Flux and/or Mono stream multiple times (possible?)

I have the method below, where I am calling several ReactiveMongoRepositories in order to receive and process certain documents. Since I am kind of new to Webflux, I am learning as I go.

To my feeling the code below doesn't feel very efficient, as I am opening multiple streams at the same time. This non-blocking way of writing code makes it complicated somehow to get a value from a stream and re-use that value in the cascaded flatmaps down the line.

In the example below I have to call the userRepository twice, since I want the user at the beginning and than later as well. Is there a possibility to do this more efficiently with Webflux?

    public Mono<Guideline> addGuideline(Guideline guideline, String keycloakUserId) {
        Mono<Guideline> guidelineMono = userRepository.findByKeycloakUserId(keycloakUserId)
                .flatMap(user -> {
                    return teamRepository.findUserInTeams(user.get_id());
                }).zipWith(instructionRepository.findById(guideline.getInstructionId()))
                .zipWith(userRepository.findByKeycloakUserId(keycloakUserId))
                .flatMap(objects -> {
                    User user = objects.getT2();
                    Instruction instruction = objects.getT1().getT2();
                    Team team = objects.getT1().getT1();
                    if (instruction.getTeamId().equals(team.get_id())) {
                        guideline.setAddedByUser(user.get_id());
                        guideline.setTeamId(team.get_id());
                        guideline.setDateAdded(new Date());
                        guideline.setGuidelineStatus(GuidelineStatus.ACTIVE);
                        guideline.setGuidelineSteps(Arrays.asList());
                        return guidelineRepository.save(guideline);
                    } else {
                        return Mono.error(new InstructionDoesntBelongOrExistException("Unable to add, since this Instruction does not belong to you or doesn't exist anymore!"));
                    }
                });
        return guidelineMono;
    }

Upvotes: 0

Views: 758

Answers (1)

Toerktumlare
Toerktumlare

Reputation: 14732

i'll post my earlier comment as an answer. If anyone feels like writing the correct code for it then go ahead.

i don't have access to an IDE current so cant write an example but you could start by fetching the instruction from the database.

Keep that Mono<Instruction> then you fetch your User and flatMap the User and fetch the Team from the database. Then you flatMap the team and build a Mono<Tuple> consisting of Mono<Tuple<User, Team>>.

After that you take your 2 Monos and use zipWith with a Combinator function and build a Mono<Tuple<User, Team, Instruction>> that you can flatMap over.

So basically fetch 1 item, then fetch 2 items, then Combinate into 3 items. You can create Tuples using the Tuples.of(...) function.

Upvotes: 1

Related Questions