WebFlux 添加阻塞逻辑
WebFlux Adding Blocking Logic
我想知道如何在创建新对象之前进行一些验证检查?
@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")));
}
如何以非阻塞方式添加验证检查?
也许是这样的东西,没有运行代码,但你明白了它的要点。
@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();
}
如果您只需要做简单的 non-blocking 检查,即检查一些字段(或者通常 - 不需要再玩 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
(例如调用另一个网络服务),则需要使用 'subscribing' 运算符,例如 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
}
我想知道如何在创建新对象之前进行一些验证检查?
@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")));
}
如何以非阻塞方式添加验证检查?
也许是这样的东西,没有运行代码,但你明白了它的要点。
@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();
}
如果您只需要做简单的 non-blocking 检查,即检查一些字段(或者通常 - 不需要再玩 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
(例如调用另一个网络服务),则需要使用 'subscribing' 运算符,例如 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
}