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是唯一的方法吗?如果我有许多逻辑检查怎么办?如果我一直将代码嵌套在其中会看起来很难看?这比命令式要困难得多,如果有大量验证和奥吉斯