Reactive Programming is a "chameleon"! :-) It can be understood as "a style of micro-architecture involving intelligent routing and consumption of events, all combining to change behaviour"1; or it can be defined as "a programming paradigm oriented around data flows and the propagation of change"2. It has something to do with the Reactive Manifesto. Functional programming comes to mind when thinking about reactive programming. And it is a software development field where a lot of interesting progress is being made! Lots to discuss here!
My objective is to register my thoughts and reflections while researching reactive programming, in the hope that it will help others understand a bit more about it and how it can be used to address current (and future) software development challenges.
Observable, Flow, Flux...
Andre Staltz, in his article The introduction to Reactive Programming you've been missing, goes right to the point when he affirms that:
Reactive programming is programming with asynchronous data streams3. (...) On top of that, you are given an amazing toolbox of functions to combine, create and filter any of those streams.
I recommend reading Andre's text attentively because it is a good practical introduction to reactive programming (how to think about it and how to write reactive code), and it helps build the foundation for further study. The diagrams are particularly worth paying attention to because they are a common means to describe and model streams behaviors and transformations.
Now, I admit that in the beginning I associated reactive programming more with Akka and its programming model. That is because some months ago I read the Reactive Manifesto, and Message Driven (asynchronous message passing) was an idea that I associated directly to Akka (reinforced by the fact that some of the manifesto's authors are related with Scala and Akka). Imagine my surprise when I discovered that the Akka Stream library!
Akka is indeed a reactive framework, and reactive systems can be built using it. But what I think is most important is that the main abstraction of reactive programming is async data streams. As Andre reinforces in his text:
Functional Reactive Programming?
Andre's text also highlights the fact that streams can be combined to generate derived streams. This brings functional programming into mind, because:
- As far as I know, reactive libraries generally implement streams as immutable data structures - i.e., we don't change a stream in place, we apply a transformation to derive a new stream from a source stream.
- These transformation operators have parallels with functional methods for processing collections, lazy collections, Java 8 Streams (they are not reactive streams):
- Reactive programming is not imperative but declarative: you create a blueprint for what needs to be done, not a sequence of steps that has to be executed in a particular order, in a particular moment.
Probably because of these similarities, FRP - Functional Reactive Programming - and RP were considered synonymous. But of course it is possible to write reactive systems without a functional language, so FRP is nowadays considered a misnomer.
What is it good for?
Read this write-up from Netflix and you'll begin to have an idea of what can be accomplished with reactive programming.
Netflix's post has cool points that I'd like to highlight:
- Reactive programming is a way to achieve greater levels of concurrency. This is aligned, in my opinion, with the Responsive characteristic of reactive systems as stated by the Reactive Manifesto.
- Comparison with other approaches for concurrent programming (Futures, Callbacks). Follow the links in the sections to see code that illustrates the authors' arguments.
- Reactive service layer: this is really what made it all "click" in my mind about reactive programming applicability. Read more than once to allow the ideas to sink into your brain!
There is a series of posts from Spring that helped me deepen the idea of "reactive service layer" and how a system could be entirely reactive. The first and second parts prepare us for the Reactive all the Way Down section in the third part. My conclusion after reading that was: "Wow, an 'all-the-way-down' reactive system could squeeze every drop of computational power available in the infrastructure." (Any blocking call would be put aside while waiting for a response, meanwhile something else would be using the processor.) That resonates well with the Elastic part of the Reactive Manifesto, doesn't it?
So what is going on?
At first I thought it was a kind of ReactiveX competitor, where several companies were trying to conceive a specification and implement it. This was a misunderstanding: it is actually an effort to define a standard for stream processing (with non-blocking back pressure, mind you), but it is not a library per se. Library implementors code against a set of interfaces, abiding by the rules expressed by the specification. The result is twofold:
- Each implementor is able to define its own client-facing API (e.g. its own DSL or data types3), with the interfaces and rules being part of the core of the created libraries;
- The different implementations are able to inter-operate, specifically regarding back pressure (i.e. the ability of a consumer/subscriber to signal its rhythm of events consumption to a producer).
You may want to take a look at Dádiv Karnok's Advanced Reactive Java. Although the text deals with operation-fusion, an advanced topic in reactive programming, the section Generations is enlightening about how reactive libraries have been progressing and what the future may hold. (By the way, Akka is a 3rd generation library, so I was not that far off in the end!)
What to do now?
This question kept crossing my mind the entire time I was researching reactive programming. I think that it is time to experiment. Why? Think about how we currently develop systems:
- Is it a monolithic, isolated WAR file? Probably not... To complete a "business rule" it is necessary to reach for a variety of other remote, independent services. If our code blocks are waiting for each response, the resulting system will not be responsive for the user.
- How many users are expected? Are there (un)expected usage peaks? Does the system scale to accommodate these peaks? From big corporations to small start-ups, all are exposed to global markets, users from anywhere in the world, millions of them. We don't want to lose customers, so our systems have to be resilient and scalable.
So I would say that if reactive programming is not mainstream in your company, try to experiment with it. Probably you'll find it is applicable somewhere, and if nothing else you can at least build knowledge about it.
Reactive programming is such a cool subject, with a wealth of information and possibility. I hope my thoughts were helpful for anyone interested in reactive programming to paint a clearer picture about it. The linked resources are invaluable sources to expand/consolidate the ideas that I presented briefly here. Hopefully this was enough to get you excited about writing reactive code for yourself!
Asynchronous data streams are given different names by different libraries: Observable by ReactiveX, Flux/Mono by Project Reactor, and Flow by Akka Stream. Probably other libraries use other names for the same concept... ↩
Matheus Eduardo Machado Moreira
I'm a software developer with 13+ year of experience, working mainly with Java backend technologies. I love my wife and family, like to play games and to ride motorcycles.