简体   繁体   中英

Where to use Mono/Flux?

I'm kind of forced to switch to reactive programming (and in a short time frame), using WebFlux and I'm having a really hard time understanding it. Maybe because the lack of examples or because I never did functional programming.

Anyways, my question is where to use Mono/Flux and where can I work with normal objects? Eg my controller is waiting for a @Valid User object, should that be @Valid Mono or something like Mono<@Valid User>? If let's say it was just a User object, I pass it to my service layer, and I want to encode the password before saving it to the reactive MongoDb, should I write:

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

Or it should be something like

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

In other words, am I forced to use this pipeline thing EVERYWHERE to maintain reactiveness or doing some steps the imperative way, like unwrapping the object, working on it, and wrapping it back is OK?

I know my question seems to be silly but I don't have the big picture at all, reading books about it didn't really help yet, please be gentle on me. :)

Use pipelining when you require sequential, asynchronous and lazy execution. In all other cases (when you are using a non-blocking code) you're free to choose any approach and it's generally better to use the simplest one.

Sequential non-blocking code can be organised in functions that you can integrate with reactive pipeline using map/filter/doOnNext/... components.

For example, consider the following Order price calculation code.

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)
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM