Как связать ответы от разных сервисов, чтобы создать ответ Flux, используя «эти ответы» в WebFlux?

Контекстуализация проблемы:

  1. Я пытаюсь связать данные из нескольких сервисов, чтобы агрегировать / объединить их ответы;

    1. Моя цель - создать финальный поток со списком объектов, созданных из «объединенных ответов».

      1. Слияние основано на 2 сервисах (userService + postService)

        1. Below is the code for the above situation:

Код:

@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));
                         }
                        );
    }
}

Вопрос:

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

Текущий проблемный ответ JsonResponse (почтальон):

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

Обновление:

Решение найдено

    @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();
                });
    }

Решение JsonResponse (Почтальон):

[
    {
        "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"
                    }
                ]
            }
        ]
    }
]

Большое спасибо за любую помощь


comment
что такое conv? пожалуйста, предоставьте код компиляции   -  person Toerktumlare    schedule 28.05.2021
comment
@Toerktumlare Спасибо, чувак. Я улучшил текст вопроса, чтобы прояснить свои сомнения. Нет, вы можете видеть немного больше, ясно. Conv - это DataMapper, который преобразует мою сущность в DTO. Спасибо   -  person PaulDev    schedule 01.06.2021
comment
Я бы посоветовал вам в целом избегать мутации объектов, поскольку webflux следует полуфункциональному подходу, жизнь станет намного проще, если вы будете работать с неизменяемыми объектами. Вы действительно не раскрыли, что делает ваше отображение. Если findAll возвращает поток, почему бы не сделать это с помощью flatmap и не выполнить вызов веб-клиента для каждого пользователя, а затем при возврате каждого веб-клиента вызвать flatMap и построить свой dto, когда у вас действительно есть вся информация, необходимая для его создания, и избежать полного изменения.   -  person Toerktumlare    schedule 01.06.2021