Где использовать Mono / Flux? - PullRequest
       10

Где использовать Mono / Flux?

0 голосов
/ 27 октября 2018

Я вынужден переключиться на реактивное программирование (и в короткие сроки), используя WebFlux, и мне очень трудно это понять. Возможно, из-за отсутствия примеров или потому, что я никогда не занимался функциональным программированием.

В любом случае, мой вопрос: где использовать Mono / Flux и где я могу работать с обычными объектами? Например. мой контроллер ожидает объект @Valid User, это должен быть @Valid Mono или что-то вроде Mono <@Valid User>? Если, скажем, это был просто объект User, я передаю его на уровень обслуживания и хочу зашифровать пароль перед сохранением его в реактивном MongoDb, если я напишу:

User.setPassword(...);
return reactiveMongoDbRepository.save(user); //returns Mono<User> which is returned by the Controller to the View

Или это должно быть что-то вроде

return Mono.just(user).map.flatmap(setPasswordSomewhereInThisHardToFollowChain).then.whatever.doOnSuccess(reactiveMongoDbRepository::save);

Другими словами, я вынужден использовать эту конвейерную вещь ВЕЗДЕ, чтобы поддерживать реактивность или делать какие-то шаги императивным способом, таким как разворачивание объекта, работа с ним и его обертывание - это нормально?

Я знаю, что мой вопрос кажется глупым, но у меня нет общей картины, чтение книг о нем еще не очень помогло, пожалуйста, будьте нежны со мной. :)

1 Ответ

0 голосов
/ 29 октября 2018

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

Последовательный неблокирующий код может быть организован в функции, которыеВы можете интегрироваться с реактивным конвейером, используя компоненты map / filter / doOnNext / ....

Например, рассмотрите следующий Order код расчета цены.

class PriceCalculator {

  private final Map<ProductCode, Price> prices;

  PriceCalculator(Map<ProductCode, Price> prices) {
    this.prices = prices;
  }

  PricedOrder calculatePrice(Order order) { // doesn't deal with Mono/Flux stuff
    Double price = order.orderLines.stream()
      .map(orderLine -> prices.get(orderLine.productCode))
      .map(Price::doubleValue)
      .sum();
    return new PricedOrder(order, price);
  }
}

class PricingController {

  public Mono<PricedOrder> getPricedOrder(ServerRequest request) {
    OrderId orderId = new OrderId(request.pathVariable("orderId"));
    Mono<Order> order = orderRepository.get(orderId);
    return order.map(priceCalculator::calculatePrice)
  }
}
...