Using other reactive programming libraries

Learn how to integrate Mutiny with RX Java or Reactor.

You may need to integrate libraries exposing an API using other reactive programming libraries such as RX Java or Reactor. Mutiny has a built-in conversion mechanism to ease that integration.

Picking the right dependency

You need to add another dependency to access the converters. Each artifact contains the converters for a specific reactive library. Pick the right one and add it to your project:

<!-- Mutiny <-> Reactor -->
<dependency>
  <groupId>io.smallrye.reactive</groupId>
  <artifactId>mutiny-reactor</artifactId>
  <version>0.11.0</version>
</dependency>

<!-- Mutiny <-> RX Java -->
<dependency>
  <groupId>io.smallrye.reactive</groupId>
  <artifactId>mutiny-rxjava</artifactId>
  <version>0.11.0</version>
</dependency>

Integration with Project Reactor

Project Reactor is a popular reactive programming library. It offers two types: Mono and Flux, both implementing Reactive Stream Publisher.

To use the Reactor <→ Mutiny converter, add the following imports to your class:

import io.smallrye.mutiny.converters.multi.MultiReactorConverters;
import io.smallrye.mutiny.converters.uni.UniReactorConverters;

Converting a Flux or a Mono into a Multi

Both Flux and Mono implement Publisher. As a result, we can use the Reactive Streams interoperability to convert instances from Flux<T> and Mono<T> to Multi<T>:

Multi<T> multiFromFlux = Multi.createFrom().publisher(flux);
Multi<T> multiFromMono = Multi.createFrom().publisher(mono);

Converting a Flux or a Mono into a Uni

As you can create Uni from a Publisher, the same approach can be used to create Uni instances:

Uni<T> uniFromFlux = Uni.createFrom().publisher(flux);
Uni<T> uniFromMono = Uni.createFrom().publisher(mono);

When a Flux or Mono sends the completion event without having emitted any item, the resulting Uni emits null.

When converting a Flux to Uni, the resulting Uni emits the first item. After that emission, it cancels the subscription to the Flux.

Converting a Multi into a Flux or Mono

Converting a Multi into a Flux or a Mono uses the Reactive Streams interoperability:

Flux<T> fluxFromMulti = Flux.from(multi);
Mono<T> monoFromMulti = Mono.from(multi);

Converting a Uni into a Flux or Mono

Converting a Uni into a Flux or a Mono requires a converter, as Uni does not implement Reactive Streams.

Flux<T> fluxFromUni = uni.convert().with(UniReactorConverters.toFlux());
Mono<T> monoFromUni = uni.convert().with(UniReactorConverters.toMono());

If the Uni emits null, it sends the completion event.

Using converter instead of Reactive Streams

While Reactive Streams interoperability is convenient, Mutiny also provides converters to create Flux and Mono from Uni and Multi:

Mono<String> mono = uni.convert().with(UniReactorConverters.toMono());
Flux<String> flux = uni.convert().with(UniReactorConverters.toFlux());
Mono<String> mono = multi.convert().with(MultiReactorConverters.toMono());
Flux<String> flux = multi.convert().with(MultiReactorConverters.toFlux());

Integration with RX Java

RxJava is another popular reactive programming library. It offers 5 types: Completable (no item), Single (one item), Maybe (0 or 1 item), Observable (multiple items), Flowable (multiple items, implements Reactive Stream Publisher).

To use the RxJava <→ Mutiny converter, add the following imports to your class:

import io.smallrye.mutiny.converters.multi.MultiRxConverters;
import io.smallrye.mutiny.converters.uni.UniRxConverters;

Converting an Observable or a Flowable into a Multi

Both Observable and Flowable are item streams. However, Observable does not implement Publisher and so does not have back-pressure support.

To create Multi from an Observable, you need a specific converter:

Multi<T> multiFromObservable = Multi.createFrom()
        .converter(MultiRxConverters.fromObservable(), observable);

Converting a Flowable is easier, as it’s a Publisher:

Multi<T> multiFromFlowable = Multi.createFrom().publisher(flowable);

Converting a Completable, Single or Maybe into a Multi

To create a Multi from a Completable, Single or Maybe you need specific converters, as none of these types implement Reactive Streams.

Multi<Void> multiFromCompletable = Multi.createFrom()
        .converter(MultiRxConverters.fromCompletable(), completable);
Multi<T> multiFromSingle = Multi.createFrom()
        .converter(MultiRxConverters.fromSingle(), single);
Multi<T> multiFromMaybe = Multi.createFrom()
        .converter(MultiRxConverters.fromMaybe(), maybe);
Multi<T> multiFromEmptyMaybe = Multi.createFrom()
        .converter(MultiRxConverters.fromMaybe(), emptyMaybe);
  • Creating a Multi from a Completable always produces a Multi<Void> that only emits the completion or failure event.

  • Creating a Multi from a Single produces a Multi. That Multi emits the item and then completes it.

  • Creating a Multi from a Maybe produces a Multi. That Multi emits the item (if any) and then completes it. If the Maybe is empty, then the created Multi emits the completion event.

When a Completable, Single, or Maybe emits a failure, then the resulting Multi emits that failure.

Converting an Observable or a Flowable into a Uni

To create a Uni from an Observable, you need to use a specific converter:

Uni<T> uniFromObservable = Uni.createFrom().converter(
        UniRxConverters.fromObservable(), observable);

The creation from a Flowable can be done using the Reactive Streams interoperability:

Uni<T> uniFromFlowable = Uni.createFrom().publisher(flowable);

In both cases, it cancels the subscription to the Flowable or Observable after receiving the first item. If the Flowable or Observable completes without items, the Uni emits a null item.

Converting a Completable, Single or Maybe into a Uni

To create a Uni from a Completable, Single, or Maybe, you need to use a specific converter:

Uni<Void> multiFromCompletable = Uni.createFrom()
        .converter(UniRxConverters.fromCompletable(), completable);
Uni<T> multiFromSingle = Uni.createFrom()
        .converter(UniRxConverters.fromSingle(), single);
Uni<T> multiFromMaybe = Uni.createFrom()
        .converter(UniRxConverters.fromMaybe(), maybe);
Uni<T> multiFromEmptyMaybe = Uni.createFrom()
        .converter(UniRxConverters.fromMaybe(), emptyMaybe);

Converting a Completable to a Uni always produces a Uni<Void>, that emits either null once the Completable completes or the failure if it fails. The Maybe to Uni conversion emits a null item if the Maybe completes without an item.

Converting a Multi into a RX Java objects

The conversion from a Multi to the various RX Java objects is done using converters:

Completable completable = multi.convert()
        .with(MultiRxConverters.toCompletable());
Single<Optional<T>> single = multi.convert()
        .with(MultiRxConverters.toSingle());
Single<T> single2 = multi.convert()
        .with(MultiRxConverters
                .toSingle().onEmptyThrow(() -> new Exception("D'oh!")));
Maybe<T> maybe = multi.convert()
        .with(MultiRxConverters.toMaybe());
Observable<T> observable = multi.convert()
        .with(MultiRxConverters.toObservable());
Flowable<T> flowable = multi.convert()
        .with(MultiRxConverters.toFlowable());

The creation of a Completable from a Multi discards all the items emitted by the Multi. It only forwards the completion or failure event.

Converting a Multi into a Single returns a Single<Optional<T>>, as the Multi may complete without items. You can also produce a Single<T> and emit a failure event if the Multi completes without items. You can configure the thrown exception using onEmptyThrow.

You can also create a Flowable from a Multi using: Flowable.fromPublisher(multi).

Converting a Uni into a RX Java type

Similarly to the conversion from a Multi into an RX Type, converting a Uni requires a converter:

Completable completable = uni.convert().with(UniRxConverters.toCompletable());
Single<Optional<T>> single = uni.convert().with(UniRxConverters.toSingle());
Single<T> single2 = uni.convert().with(UniRxConverters.toSingle().failOnNull());
Maybe<T> maybe = uni.convert().with(UniRxConverters.toMaybe());
Observable<T> observable = uni.convert().with(UniRxConverters.toObservable());
Flowable<T> flowable = uni.convert().with(UniRxConverters.toFlowable());

The creation of a Completable from a Uni discards the item and sends the completion signal after emission.

Converting a Uni into a Single returns a Single<Optional<T>>, as the Uni may emit null. You can also produce a Single<T> and emits a failure event if the Uni sends null. Configure the failure to forward using failOnNull.

The creation of a Maybe, Flowable, or an Observable from a Uni produces an empty Maybe, Flowable, or Observable if the Uni emits null. For Flowable and Observable, if the Uni emits a non-null item, that item is emitted, followed immediately by the completion signal.