Преобразование Spring Webflux Mono в любую, желательно без блокировки? - PullRequest
0 голосов
/ 24 апреля 2018

Я использую Kotlin и Arrow и WebClient от spring-webflux. Что я хотел бы сделать, так это преобразовать экземпляр Mono в Either .

Экземпляр Either создается путем вызова Either.right(..), если ответ WebClient успешен, или Either.left(..), когда WebClient возвращает ошибку.

Я ищу метод Mono, похожий на Either.fold (..) , где я могу отобразить успешный и ошибочный результат и вернуть тип, отличный от Mono. Примерно так (псевдокод не работает):

val either : Either<Throwable, ClientResponse> = 
                   webClient().post().exchange()
                                .fold({ throwable -> Either.left(throwable) },
                                      { response -> Either.right(response)})

Как можно идти?

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

Нет метода fold на Mono, но вы можете добиться того же, используя два метода: map и onErrorResume. Это будет выглядеть примерно так:

val either : Either<Throwable, ClientResponse> = 
               webClient().post()
                          .exchange()
                          .map { Either.right(it) }
                          .onErrorResume { Either.left(it).toMono() }
0 голосов
/ 24 апреля 2018

Я не очень знаком с этой библиотекой Arrow и с типичным вариантом ее использования, поэтому я буду использовать отрывки Java, чтобы высказать свою точку зрения.

Сначала я хотел бы отметить, что этот тип кажется блокирующим и не ленивым (в отличие от Mono). Перевод Mono на этот тип означает, что вы заблокируете свой код и не должны делать этого, например, в середине обработчика контроллера или заблокируете весь сервер.

Это более или менее эквивалентно этому:

Mono<ClientResponse> response = webClient.get().uri("/").exchange();
// blocking; return the response or throws an exception
ClientResponse blockingResponse = response.block();

При этом, я думаю, вы должны быть в состоянии преобразовать Mono в этот тип, либо вызвав block() для него и блока try/catch вокруг него, либо превратив сначала в CompletableFuture сначала, как:

Mono<ClientResponse> response = webClient.get().uri("/").exchange();
Either<Throwable, ClientResponse> either = response
        .toFuture()
        .handle((resp, t) -> Either.fold(t, resp))
        .get();

Возможно, есть лучшие способы сделать это (особенно с помощью встроенных функций), но все они должны включать блокировку Mono.

...