Reactive Messaging with Helidon 2.0

Daniel Kec
Helidon
Published in
4 min readMar 25, 2020

Asynchronous messaging is a commonly used form of communication in the world of microservices and Reactive Messaging for MicroProfile specification is a logical response to the need for formalizing ways to connect things together.

What is the best way to communicate asynchronously? Via Reactive Streams of course! To formalize manipulation with reactive streams, another specification had to emerge and that is MicroProfile Reactive Streams Operators. Reactive messaging heavily depends on standardized operators to provide great portability between existing implementations.

The pre-release version of Helidon’s Reactive Messaging and Reactive Streams Operators are included in the Helidon 2.0.0-M2 release.

Note: Pre-release versions are experimental and not intended for production use. APIs and features are not yet fully tested and are subject to change.

Reactive Messaging

Connect things together — that’s exactly what it does! Reactive Messaging gives you the “plumbing tools” needed to configure reactive streams to work more efficiently with asynchronous messaging. It does this by connecting named pairs of methods or connectors with channels.

Let’s have a look at how it works:

Channel between two methods

In this example we are connecting 3 messaging methods with 2 channels. The first method is invoked at assembly, preparing the publisher of raw Integers to be connected to the second method rewrapMessageManually.

The second method is invoked for every item coming from the publisher. Messaging automatically wraps every integer item to a Message wrapper — based on the second method’s argument type. The user code in the method then unwraps the original payload, converts it to String, and wraps it again. The method rewrapMessageManually is connected to the third method which is consuming every payload coming from upstream and printing it to the standard output. Again, messaging automatically unwraps payload from the Message wrapper based on the method signature.

The example is fairly simple, but when you realize that messaging channels can connect methods across all application-scoped beans and various connectors, you can see how powerful such tooling can be. Imagine connecting JMS with Kafka while peeking or transforming every message in a clean, reactive way like this!

Connectors

Messaging just between beans in the same application context would be just a fancy toy without configurable connectors. We are preparing a full blown Kafka connector for Helidon 2.0 with many more coming after that. But there is nothing easier than creating a custom made connector, tailored specifically to a particular use case. After all, it’s just a bean!

Then just configure channels to be connected with MicroProfile Config

Now let’s stream something:

Consume something from connector:

As you can see the configuration is simple and straightforward, exactly as microservices should be.

Now we need a way to acknowledge the message reception. The acknowledgement can be quite important for committing offset of pulled messages from Kafka or JMS session when we want to build a resilient messaging system.

Acknowledgement

As you probably already noticed in the very first example, reactive messaging provides semi-automatic wrapping for all streamed items. The wrapper envelope Message doesn’t only carry a payload, but also a callback which is submitted when the message is acknowledged. Messaging provides various ways to acknowledge a message either automatically or manually.

Simplest usage:

Let’s leave it to messaging:

There are a lot more possibilities, check the specification for an exhaustive list of all the variants.

Reactive Streams Operators

In comparison with APIs of other reactive libraries, MicroProfile Reactive Streams Operators may seem to be a little Spartan as operators SPI is abstracting user code from actual implementation with a limited number of the most crucial operators.

But don’t worry, you can still continue to use your favorite reactive library. All that is needed from the reactive library is to implement reactive streams API which is quite common. Let’s compare some of our possibilities:

RxJava:

Reactor:

See? Not a problem because we have all the plumbing tools we need!

And the same goes for Messaging, there is variety of messaging method signatures available, allowing direct interaction over reactive streams Publisher/Subscriber/Processor:

Reactive Streams in Helidon SE

MicroProfile Reactive Streams Operators are available in Helidon SE just as any other reactive streams library. All you need to do is add a dependency and you are good to go.

Helidon reactive engine

Helidon comes with its own reactive engine, which means its own reactive operators and its own API based on java.util.concurrent.Flow. There is a lot you can do with Multi and Single — enough for another whole series of articles! The example below gives you a preview:

We are really proud that for Helidon 2.0 a brand new implementation of Helidon’s reactive engine has been contributed to by the world-renown reactive programming expert, project lead of RxJava and co-father of project Reactor, Dr. David Karnok. This contribution brings not only a huge performance leap, but also a lot of new functionality, a battery of new, super cool operators and, of course, a fine-tuning for Helidon’s own MicroProfile Reactive Streams Operators implementation.

So the reactive messaging in Helidon 2.0 can fly fast!

Try the new reactive features yourself. Check out this sample utilizing Reactive Messaging with Server Sent Events, which is already running on the freshly released Helidon 2.0.0-M2. Or a screencast featuring the sample https://youtu.be/-c7nVy3LM3s.

And don’t forget to leave us your feedback as a comment here, in our official Twitter or on our official Slack channel, we appreciate it.

Happy messaging!

--

--