WebFlux Добавление логики блокировки - PullRequest
0 голосов
/ 09 июля 2019

Мне интересно, как выполнить некоторые проверки достоверности перед созданием нового объекта?

@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")));
}

Как добавить проверку проверки неблокирующим способом?

Ответы [ 2 ]

1 голос
/ 09 июля 2019

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

Может быть, что-то вроде этого, не запускайте код, но вы понимаете его суть.

@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();
}
...