Если вам нужно выполнить только простые неблокирующие проверки, т. Е. Проверить некоторые поля (или вообще - не требовать воспроизведения другого 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
(например, вызов другого веб-сервиса), для этого потребуется использовать операторы «подписки», такие как 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
}