compose() vs. transform() vs. as() vs. map() in Flux and Mono

Andrew Sasha picture Andrew Sasha · Nov 17, 2017 · Viewed 10.2k times · Source

Recently, I decided to try spring 5 with projectreactor.io (io.projectreactor:3.1.1).

Does anyone know what the best case of using this functions? What cons and pros of using each of them and where they should be used?

Good examples will be helpful.

Answer

Simon Baslé picture Simon Baslé · Nov 17, 2017

You have two broadly different categories of operators here:

Operators that work on the Flux itself

transform and compose are for code mutualization

When you compose chains of operators regularly and you have common operator usage patterns in your application, you can mutualize this code or give it a more descriptive name by using compose and transform.

The difference between the two is when the mutualized operators are applied: transform applies them at instantiation, while compose applies them at subscription (allowing for dynamic choice of the added operators).

Have a look at the reference documentation for more details and examples.

as

This is a convenience shortcut to apply a Function to the whole Flux while keeping the whole code in a fluent style. An example would be to convert to a Mono (as shown in the javadoc), but it can also helps with external operators that are implemented in a factory method style.

Take reactor-addons MathFlux for example, and compare:

MathFlux.sumInt(Flux.range(1, 10)
                    .map(i -> i + 2)
                    .map(i -> i * 10))
        .map(isum -> "sum=" + isum);

To:

Flux.range(1, 10)
    .map(i -> i + 2)
    .map(i -> i * 10)
    .as(MathFlux::sumInt)
    .map(isum -> "sum=" + isum)

(this can help you deal with the fact that, unlike Kotlin, Java doesn't have extension methods :) )

Operator that works on the data that goes through the Flux

map is all about the data. It applies a 1-1 transformation function to each element in the source, as they become available.

In the MathFlux example above, map is successively used to add 2 to each original integer, then again to multiply each number in the sequence by 10, then a third time at the end to produce a String out of each sum.