Search code examples
spring-bootredisdroolsspring-webfluxproject-reactor

How to think in reactive programming manner and convert traditional oops application into reactive application


In the traditional way of writing an application, I have divided the application into a set of tasks and execute them sequentially.

  1. Get a list of rules for a given rule group from Redis
  2. Construct facts input and fire the rules.
  3. compute a response for the request by hitting multiple rules (Rule group A might depend on the Rule group B result).
  4. send the response back to the caller.

If I was to implement the above steps using the spring web flux reactive manner, how do I achieve it?

  1. I have used ReactiveRedis to get the data from redis. ReactiveRedisOperations.opsForValue().get(ruleGroupName) does not return anything until we subscribe() to it. But ReactiveRedisOperations.opsForValue().get(ruleGroupName).subscribe() makes the processing thread reactive and the execution goes to next line in the application without waiting for the Subscriber to execute.

  2. As my next steps depend on the data returned by Redis, I have used the block() option to make it wait.

In the real-world how does one tackle a situation like this? Thanks in advance.

PS: New to spring web flux and reactive programming.


Solution

  • Instead of separating logical steps by putting them on a new line, like in imperative programming, reactive programming uses method composition and chaining (the operators).

    So once you get a Flux<T> or a Mono<T> (here your rules from Redis), you need to chain operators to build up your processing steps in a declarative manner.

    A step that transforms each input element <T> into a single corresponding element <R>, in memory and without latency, is typically expressed as a map(Function<T, R>) and produces a Flux<R>. In turn, chain further operators on that.

    A step that either transforms 1 element <T> to N elements <R> and/or does so asynchronously (ie the transformation returns a Flux<R> for each T) is typically expressed as a flatMap(Function<T, Publisher<R>>).

    Beyond that, there is a rich vocabulary of specialized operators in Reactor that you can explore.

    In the end, your goal is to chain all these operators to describe your processing pipeline, which is going to be a Mono<RETURN_TYPE> or Flux<RETURN_TYPE>. RETURN_TYPE in webflux can either be a business type that Spring can marshall or one of the Spring response-oriented classes.