Buena noches. Estoy estudiando la programación reactiva y me he encontrado con el siguiente problema.
Estoy corriendo dos consultas en paralelo a la base de datos y desea combinar los resultados y se da vuelta
@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;
});
Pero el punto es que el comentario puede estar vacío, y luego esperar a devolver el JSON de dicha estructura
{
"id": "5e6cbf395214a42f51b57121",
"name": "Bob",
"surname": null,
"comment": null
}
En vez consigo una respuesta vacía. Al parecer, esto se debe al mono zip, pero de qué otra manera puedo combinar los resultados, mientras se mantiene el paralelismo de consultas
Mis entidades:
@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;
}
¿Cómo puedo resolver esta situación?
Zip/ZipWith
necesitará elementos para producir su salida. Si se pudiera estar vacío, podría utilizar a continuación métodos para establecer un valor por defecto.
defaultIfEmpty(new Comment())
oswitchIfEmpty(Mono.fromSupplier(() -> new Comment())
Si no desea utilizar new Comment()
y conjunto null
de comentario objeto, podemos tratar de esta manera.
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;
});