Projectreactor: параллельное выполнение запросов и объединение результатов - PullRequest
1 голос
/ 14 марта 2020

Добрый вечер. Я изучаю реактивное программирование и столкнулся со следующей проблемой:

Я запускаю два параллельных запроса к базе данных и хочу объединить результаты и вернуть их

    @GetMapping
    public Mono<User> get(@RequestParam("id") String id, @RequestParam("cId") String cId) {
        Mono<User> userMono = Mono.fromCallable(() -> userServ.get(id))
                .flatMap(userMono1 -> userMono1)
                .subscribeOn(Schedulers.boundedElastic());

        Mono<Comment> ger = Mono.fromCallable(() -> commentServ.ger(cId))
                .flatMap(commentMono -> commentMono)
                .subscribeOn(Schedulers.boundedElastic());


        return Mono.zip(userMono, ger)
                .map(pair -> {
                    User t1 = pair.getT1();
                    t1.setComment(pair.getT2());
                    return t1;
                });

Но суть является то, что комментарий может быть пустым, и тогда я ожидаю, чтобы вернуть json такой структуры

{
    "id": "5e6cbf395214a42f51b57121",
    "name": "Bob",
    "surname": null,
    "comment": null
}

Вместо этого я получаю пустой ответ. По-видимому, это связано с моно-zip, но как еще можно объединить результаты, сохраняя параллелизм запросов

Мои объекты:

@Document
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Comment {
    @Id
    String id;
    String userId;
    String comment;
}

@Document
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    @Id
    private String id;
    private String name;
    private String surname;
    private Comment comment;
}

Как я могу разрешить эту ситуацию?

1 Ответ

2 голосов
/ 14 марта 2020

Zip/ZipWith нужны элементы, чтобы произвести их вывод. Если он может быть пустым, вы можете использовать следующие методы, чтобы установить какое-либо значение по умолчанию.

  • defaultIfEmpty(new Comment()) или
  • switchIfEmpty(Mono.fromSupplier(() -> new Comment())

Если вы не хотите использовать new Comment() и установить null для комментирования объекта, мы можем попробовать это так.

        userMono
                .zipWith(commentMono.defaultIfEmpty(new Comment()))
                .map(pair -> {
                    User user = pair.getT1();
                    Comment comment = pair.getT2();
                    if(Objects.nonNull(comment.getUserId()))
                       user.setComment(comment);
                    return user;
                 });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...