πŸ• Reading time: 2 minutes

When we work with WebFlux, we often end up handling the output of two Monos combined together with zip. The result is an object of type Tuple2, a structure that represents an immutable pair of values. Handling lots of Tuple2s, however, can make the code less readable and harder to maintain.

πŸ“Œ The combinator variant

For this reason, there are variants of the zip, zipWith and zipWhen methods that take a combinator (an aggregation function) as a parameter, letting us get a well-typed object directly instead of a generic tuple.

// (1) Using zip methods to create a strongly-typed object instead of Tuple2
private record Car(String licensePlate, Integer numberOfDoors) {}

@Test
void test_combinator() {
    checkCar(Mono.zip(Mono.just("BMT 216A"), Mono.just(5), Car::new));
    checkCar(Mono.just("BMT 216A").zipWith(Mono.just(5), Car::new));
    checkCar(Mono.just("BMT 216A").zipWhen(t1 -> Mono.just(5), Car::new));
}

private void checkCar(final Mono<Car> carMono) {
    final Car actualCar = carMono.block();
    assertNotNull(actualCar);
    assertEquals("BMT 216A", actualCar.licensePlate());
    assertEquals(5, actualCar.numberOfDoors());
}

Thanks to this strategy, we can avoid working with generic tuples and get objects with clearly defined parameters, improving the readability and maintainability of the code.

πŸ“‘ Note: beyond two Monos

The combinator methods are available in Mono only for two elements. If we need to handle Tuple3, Tuple4 or higher, we can define a custom method:

// (2) Custom zip method for combining three Monos into a strongly-typed object, avoiding Tuple3 usage
public static <T1, T2, T3, R> Mono<R> zip(
        final Mono<T1> m1, final Mono<T2> m2, final Mono<T3> m3, final Function3<T1, T2, T3, R> mapper) {
    return Mono.zip(m1, m2, m3).map(mapTuple(mapper));
}

private static <T1, T2, T3, R> Function<Tuple3<T1, T2, T3>, R> mapTuple(final Function3<T1, T2, T3, R> mapper) {
    return tuple -> mapper.apply(tuple.getT1(), tuple.getT2(), tuple.getT3());
}

Did you enjoy this Java tip? This idea came out of an interesting moment of sharing at the company!

See you at the next pill! β˜•