Spring boot WebFlux添加块逻辑

Spring boot WebFlux添加块逻辑,spring-boot,reactive-programming,spring-webflux,project-reactor,Spring Boot,Reactive Programming,Spring Webflux,Project Reactor,我想知道在创建新对象之前如何进行一些验证检查 @Override public Mono<Child> create(CreateChildRequest specs) { final String parentId = specs.getParentId(); // TODO: Check if parent exists // parentRepository.getById(parentId) -> returns Mono<Parent&

我想知道在创建新对象之前如何进行一些验证检查

@Override
public Mono<Child> create(CreateChildRequest specs) {

    final String parentId = specs.getParentId();
    // TODO: Check if parent exists
    // parentRepository.getById(parentId) -> returns Mono<Parent>

    final Child newChild = new Child(specs.getParentId(), specs.getName());
    return childRepository.insert(newChild)
            .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "Failed to create child")));
}
@覆盖
公共Mono创建(CreateChildRequest规范){
最后一个字符串parentId=specs.getParentId();
//TODO:检查父项是否存在
//parentRepository.getById(parentId)->返回Mono
final Child newChild=newChild(specs.getParentId(),specs.getName());
返回childRepository.insert(newChild)
.switchIfEmpty(Mono.error(新的ResponseStatusException(HttpStatus.BAD_请求,“未能创建子项”));
}

如何以非阻塞方式添加验证检查?

可能类似于这样,没有运行代码,但您了解了它的要点

@Override
public Mono<Child> create(CreateChildRequest specs) {

    final String parentId = specs.getParentId();
    return parentRepository.getById(parentId)
        .doOnSuccess(parent -> {
            verify(parent).doOnSuccess(() -> {
                childRepository.insert(newChild).doOnError(throwable -> {
                    throw new ResponseStatusException(
                        HttpStatus.BAD_REQUEST,
                        "Failed to create child")
                }).doOnError(throwable -> {
                    // some error handling here if not passing validation.
                })
            })
        })
}

private Mono<Void> verify(Parent parent) {

    if(parent == null)
        return Mono.error(// some error here);
    else
        Mono.empty();
}
@覆盖
公共Mono创建(CreateChildRequest规范){
最后一个字符串parentId=specs.getParentId();
返回parentRepository.getById(parentId)
.doOnSuccess(父级->{
验证(父).doOnSuccess(()->{
childRepository.insert(newChild).doon错误(可丢弃->{
抛出新的ResponseStatusException(
HttpStatus.BAD_请求,
“未能创建子对象”)
}).doon错误(可丢弃->{
//如果未通过验证,此处会出现一些错误处理。
})
})
})
}
专用单声道验证(父级){
如果(父项==null)
返回Mono.error(//此处有一些错误);
其他的
Mono.empty();
}

如果您只需要执行简单的非阻塞检查,即检查某些字段(或者通常不需要播放另一个
Mono
/
Flux
),您可以在
doOnNext
操作符中执行,并轻松提取到其他方法。此块内引发的任何异常都将转换为
Mono.error

final String parentId = specs.getParentId();

    parentRepository.getById(parentId)
        .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "Parent does not exist")))
        .doOnNext(parent -> {
            if (parent.getSomeField() == null) { //this can be easily extracted for readability
                throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Some field must not be null");
            }
        })
        .then(Mono.just(new Child(specs.getParentId(), specs.getName()))
                .flatMap(childRepository::insert)
                .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "Failed to create child")));
如果执行检查需要涉及另一个
Mono
/
Flux
(例如调用另一个Web服务),则需要使用“订阅”操作符,如
flatMap
zip

    @Override
    public Mono<Child> create(CreateChildRequest specs) {
        final String parentId = specs.getParentId();

        parentRepository.getById(parentId)
            .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "Parent does not exist")))
            .flatMap(parent -> validate(parent))
            .then(Mono.just(new Child(specs.getParentId(), specs.getName()))
                    .flatMap(childRepository::insert)
                    .switchIfEmpty(Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "Failed to create child")));
                }

            }

Mono<Void> validate(Parent parent){
    //some non blocking io logic ending with Mono.empty or Mono.error
}
@覆盖
公共Mono创建(CreateChildRequest规范){
最后一个字符串parentId=specs.getParentId();
parentRepository.getById(parentId)
.switchIfEmpty(Mono.error(新的ResponseStatusException(HttpStatus.BAD_请求,“父级不存在”))
.flatMap(父级->验证(父级))
.then(Mono.just(新的子项(specs.getParentId(),specs.getName()))
.flatMap(childRepository::insert)
.switchIfEmpty(Mono.error(新的ResponseStatusException(HttpStatus.BAD_请求,“未能创建子项”));
}
}
Mono验证(父级){
//某些非阻塞io逻辑以Mono.empty或Mono.error结尾
}

取决于
Mono
是否可以包含null?但是您应该执行
parentRepository.getById(parentId)
然后在其上进行链接以进行检查,如果良好,则
子存储库。插入
是的,我正在寻找链接此的方法。flatmap是唯一的方法吗?如果我有许多逻辑检查怎么办?如果我一直将代码嵌套在其中会看起来很难看?这比命令式要困难得多,如果有大量验证和奥吉斯