java - WebFlux 条件平面图

标签 java reactive-programming spring-webflux project-reactor

我对 webflux 比较陌生,我想找到解决方案来避免在有条件时嵌套 flatMap:

我有 3 个简单的实体:

项目、品牌、类别。

Item基本包含:brandId和categoryId

public Mono<Item> patch(String itemId, PatchSpecs specs) {
return itemRepository.findById(itemId)
        .switchIfEmpty(Mono.error(..)))
        .flatMap(item -> {
            final String brandId = specs.getBrandId();
            if (brandId != null) {
                return brandService.getById(brandId)
                        .switchIfEmpty(Mono.error(..)))
                        .flatMap(brand -> {
                            final String categoryId = specs.getCategoryId();
                            if (categoryId != null) {
                               return categoryService.getById(categoryId)... -> return updateAndSave(..)
                            }
                            return updateAndSave(specs, item, brand, null);
                        });
            }
            else {
                final String categoryId = specs.getCategoryId();
                if (categoryId != null) {
                     return categoryService.getById(categoryId)... -> return updateAndSave(..)
                }
                return updateAndSave(specs, item, null, null);
            }

        });
}

如何防止这种分支条件 flatMaps 困惑?我无法想象如果我在项目中有另一个实体。会有更多嵌套的flatMap吗?

最佳答案

如果我很好地理解您的代码,类别和品牌是商品的可选属性。在这种情况下,我建议如下:

public Mono<Item> patch(String itemId, PatchSpecs specs)
{
    return itemRepository.findById(itemId)
                         .switchIfEmpty(Mono.error(new RuntimeException("Can not find item.")))
                         .flatMap(item -> updateAndSave(specs, item));
}

private Mono<? extends Item> updateAndSave(PatchSpecs specs, Item item)
{
    Mono<Optional<Brand>> brand = getBrand(specs.getBrandId());
    Mono<Optional<Category>> category = getCategory(specs.getCategoryId());

    return Mono.zip(Mono.just(item), brand, category)
               .flatMap(tuple -> updateAndSave(specs, tuple));
}

private Mono<Optional<Brand>> getBrand(String inputBrandId)
{
    return Mono.justOrEmpty(inputBrandId)
               .flatMap(brandId -> brandService.getById(brandId)
                                               .switchIfEmpty(Mono.error(new RuntimeException("Can not find brand."))))
               .map(Optional::of)
               .defaultIfEmpty(Optional.empty());
}

private Mono<Optional<Category>> getCategory(String inputCategoryId)
{
    return Mono.justOrEmpty(inputCategoryId)
               .flatMap(brandId -> categoryService.getById(brandId)
                                                  .switchIfEmpty(Mono.error(new RuntimeException("Can not find brand."))))
               .map(Optional::of)
               .defaultIfEmpty(Optional.empty());
}

private Mono<Item> updateAndSave(PatchSpecs specs, Tuple3<Item, Optional<Brand>, Optional<Category>> tuple)
{
    Item item = tuple.getT1();
    Brand brand = tuple.getT2().orElse(null);
    Category category = tuple.getT3().orElse(null);

    // TODO do update and save here
    return null;
}

这样扩展性更好,不需要重复和嵌套条件。请验证它是否按预期工作。

关于java - WebFlux 条件平面图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57635069/

相关文章:

android - RxJava : How to find the smaller number in a sequence

c# - 在没有 onBackpressureLatest 的情况下处理 Rx.NET 中的背压

spring-security - 启用安全性后,Spring Cloud Gateway 为所有发布请求返回 403

spring - 如何记录 Spring WebClient 响应

java - 使用 ASM 库覆盖 Java 字节码中的局部变量名称

java - JScrollBar 不显示拇指

ios - 使用 ReactiveX 管理多个上传(在 iOS 上使用 Swift 和 Alamofire)

java - 将 Python 生成的 protobuf 转换为没有 .proto 文件的 java

java - Netbeans 8.1 和 Checkstyle 插件

spring - HATEOAS 关于 Spring Flux/Mono 响应