0

Contextualization about the problem:

  1. I am trying to chain data from multiple services, in order to aggregate/merge their responses;

    1. My Goal is create a final Flux with a List of objects created from the 'Merged Responses'.

      1. The merging is based on 2 services (userService + postService)

        1. Below is the code for the above situation:

Code:

@Slf4j
@Service
@AllArgsConstructor
public class BlogService implements BlogServiceInt {

    private final UserServiceInt userService;

    private final PostServiceInt postService;

    private final CommentServiceInt commentService;

    private final ModelMapper conv;

    @Override
    public Flux<UserAllDto> findAllShowAllDto() {

        return userService
                .findAll()
                .flatMap(user -> Flux.fromIterable(List.of(conv.map(user,UserAllDto.class))))
                .flatMap(userAllDto -> {
                             postService
                                     .findPostsByAuthorId(userAllDto.getId())
                                     .map(post -> conv.map(post,PostAllDto.class))
                                     .collectList()
                                     .flatMap(list -> {
                                         if (!list.isEmpty()) userAllDto.setPosts(list);
                                         return Mono.just(userAllDto);
                                     });

                             return Flux.fromIterable(List.of(userAllDto));
                         }
                        );
    }
}

Question:

  • How do I complete 'userAllDto.setPosts',
    • by Fetching 'PostAllDto' objects creating a List of That,
      • and inserting this list in 'userAllDto.setPosts'?

Current Problematic JsonResponse (Postman):

[
    {
        "id": "60b0306f275ea3018b167dde",
        "name": "p",
        "posts": []
    },
    {
        "id": "60b03070275ea3018b167ddf",
        "name": "p",
        "posts": [
            {
                "id": null,
                "title": null,
                "listComments": []
            }
        ]
    }
]

Updating:

Solution Found

    @Override
    public Flux<UserAllDto> findAllShowAllDto() {

        return userRepo
                .findAll()
                .flatMap(user -> {
                    UserAllDto userDto = mapper.map(user,UserAllDto.class);

                    final Mono<UserAllDto> userAllDtoMono =
                            postService
                                    .findPostsByAuthorId(userDto.getId())
                                    .flatMap(post -> {
                                                 PostAllDto postDto = mapper.map(post,PostAllDto.class);

                                                 final Mono<PostAllDto> postAllDtoMono =
                                                         commentService.findCommentsByPostId(postDto.getPostId())
                                                                       .map(c -> mapper.map(c,CommentAllDto.class))
                                                                       .collectList()
                                                                       .flatMap(list -> {
                                                                    postDto.setListComments(list);
                                                                    return Mono.just(postDto);});
                                                 return postAllDtoMono.flux();})
                                    .collectList()
                                    .flatMap(list -> {
                                        userDto.setPosts(list);
                                        return Mono.just(userDto);
                                    });
                    return userAllDtoMono.flux();
                });
    }

Solution's JsonResponse (Postman):

[
    {
        "id": "60b9284e08a653638c22bd97",
        "name": "bbbbbbbb ",
        "posts": [
            {
                "postId": "60b929a808a653638c22bd9d",
                "title": "bbbbbbbbbb111111111111",
                "idAuthor": "60b9284e08a653638c22bd97",
                "listComments": [
                    {
                        "commentId": "60b92bad08a653638c22bd9e",
                        "postId": "60b929a808a653638c22bd9d",
                        "idAuthor": "60b9292e08a653638c22bd9b",
                        "text": "ccccccccccccccccc 2222"
                    },
                    {
                        "commentId": "60b92c1708a653638c22bd9f",
                        "postId": "60b929a808a653638c22bd9d",
                        "idAuthor": "60b9285908a653638c22bd98",
                        "text": "aaaaaaaaaaaaaaaaaaaa 2222"
                    }
                ]
            }
        ]
    },
    {
        "id": "60b9285908a653638c22bd98",
        "name": "aaaaaaa ",
        "posts": [
            {
                "postId": "60b9287808a653638c22bd99",
                "title": "aaaaaaa1111111111111",
                "idAuthor": "60b9285908a653638c22bd98",
                "listComments": [
                    {
                        "commentId": "60b928f408a653638c22bd9a",
                        "postId": "60b9287808a653638c22bd99",
                        "idAuthor": "60b9284e08a653638c22bd97",
                        "text": "bbbbbbbbbbbbb 1111"
                    },
                    {
                        "commentId": "60b9294a08a653638c22bd9c",
                        "postId": "60b9287808a653638c22bd99",
                        "idAuthor": "60b9292e08a653638c22bd9b",
                        "text": "ccccccccccccccccc 1111"
                    }
                ]
            }
        ]
    }
]

Thanks a lot for any help

GtdDev
  • 748
  • 6
  • 14
  • what is `conv`? please provide compiling code – Toerktumlare May 28 '21 at 06:19
  • @Toerktumlare Thx man. I have improved the question body to clarify my doubts. No, you can see, a bit more, clearly. "Conv" is a DataMapper that converts my Entity in a DTO. Thx – GtdDev Jun 01 '21 at 15:09
  • I would suggest that you in general try to avoid mutating objects, as webflux follows a semi functional aproach life will get a lot easier if you work with immutable objects. You havnt really disclosed what your mapping is doing. If `findAll` returns a flux, why not flatmap that result and do a webclient call for each user and then in the return of each webclient call flatMap and build your dto when you actually have all the information needed to build it and avoid the mutate completly. – Toerktumlare Jun 01 '21 at 16:16

0 Answers0