What It Takes To Properly Build Reactive Web Applications For The JVM
A short Q/A with Manuel Bernhardt, author of "Reactive Web Applications"
Manuel Bernhardt knows a thing of two about building distributed, Reactive web applications for the modern enterprise. Having recently published his own book on the subject, I wanted to sit down with him to ask him about what architects and developers should know about the traits of Reactive systems, why it's important to build Reactive systems using Play, Akka, and Scala rather than Spring and Java EE, how the open source community has wonderfully impacted the growth of these technologies, and whether he'd ever consider writing another book again. Enjoy the Q/A!
Lightbend: Can you tell us a little about yourself, and how you started to care about Reactive systems?
Manuel: I am a telecommunications engineer who has been fiddling with distributed systems for a long time. I don't recall having consciously started to care so much about Reactive systems in particular, but I've always been interested in how to make distributed systems robust, which is a very tricky and challenging topic. Then the Reactive Manifesto was published and I think it does a very good job at defining what it takes to make those systems robust.
Lightbend: What compelled you to write a book on this subject, and what was that process like for you?
Manuel: I have been actively involved in the Play Framework community, and kept on getting requests by various publishers for writing a book about Play because of this involvement. I always refused because I knew this was a large amount of work. Then I was in Los Angeles working on a client project who at the time was moving to Play because they needed the scaling capabilities, so I was spending a lot of time explaining all those core concepts that enable this type of massive scalability and I thought "it really would be useful to have a book about this". I went with Manning because I heard that they were a good publisher for first-time authors.
My advice if you plan on writing a technical book: set the right expectations. I knew it was going to be a lot of work for the kind of book I wanted to write (with high-quality, reality-driven example applications throughout) and ended up spending about 230 days in total working on it. I generally tried to "write" continuously (every day is ideal, or at least every week), but "writing" is in fact also a lot of research, communication overhead and programming the example applications. At this point I'd like to thank everyone who helped answer all the nagging questions I asked while writing the book :-)
Lightbend: Why Play, Akka and Scala, and not other technologies like Spring or Java EE?
Manuel: There is a pretty simple answer to this. When I started writing the book, there was no other stack on the JVM with the capabilities of Play, Akka and Scala: by which I mean coast-to-coast asynchronous computation and a ground up message-driven design. From what I know, still to this day there is no such thing in Java EE, and Spring has something called Project Reactor, but I have the impression that this is more a marketing move than a platform for building robust, Reactive systems. It still is tied to JPA, which is in my opinion incompatible with building high performance, resilient applications.
Using Scala for the book was more about personal preference than it was about possibilities. It would have been possible to write the examples in Java as well, although they'd have been more verbose. Also arguably, Scala fits the Reactive paradigm better because it is easier to model immutability in it, which is the default.
Lightbend: What is your advice to engineers looking to start building Reactive systems?
Manuel: I gave this talk called "3 Things You Need To Think Reactive", which lays out the foundation of what I think is needed to switch to a Reactive mindset: Immutability, Functions and Functional Composition.
- Immutability. Mutable state is there because in the past we had no other choice; memory was expensive. This is not true anymore, so we can afford to keep everything in memory. Immutability reduces the amount of surprises in your code. When you define something, it is not going to magically change someplace else unexpected, meaning you don't need to take special precautions (e.g. locking, which is expensive). It takes time to let go of this "bad habit" of using mutable data structures and requires more powerful coding paradigms for building apps, which brings us to functions.
- Functions. These let you build programs with immutable data easily. Instead of having data and passing it from one place to another, you model behaviour and pass the behaviour around. This allows you to bring behaviour–in other words, processing instructions–to the data, which can be used to solve problems when moving data is expensive. This is one of the core concepts on top of which Apache Spark is built upon.
- Functional composition. This helps you reduce the amount of repetition in a program by defining simple, small functions–that is to say, basic blocks of behaviour and that can be composed in order to define more complex behaviour. It's like playing with Lego bricks. Also this helps manage complexity: complex behaviour is built by composing smaller, simpler bits of behaviour, which are then easier to comprehend and manage.
Reactive applications follow the message-driven model, providing end-to-end asynchronous communication. You have to become aware of what parts of your code will block and which won't. e.g. database access is often blocking so you have to care as to how your applications deals with database access, if the API of your database is not already asynchronous.
Testing Reactive applications is a different game, because you now have concurrency built-in (by choice) in your application, so testing needs become more advanced. Akka provides utilities for this in the Akka test-kit, and testing frameworks in general start to provide good facilities for it, but you need to learn the ropes first. In this video from GeeCon 2016, I discuss a lot of this:
Lightbend: How has the OSS community played a role in this journey?
Manuel: I think it is fair to say that the Play Framework would not be what it is today if it wasn't for the amazing amount of contributions it is receiving from the community. By the way it isn't just me who is saying this, James Roper, tech lead of Play Framework up until recently (now he is the Lagom Tech Lead at Lightbend) repeatedly says this - at this point I think that it should be mentioned that this level of community involvement is in large part due to James' talented leadership of the project over the past few years.
Akka is a bit more difficult to contribute to because it is built very carefully to maximize the performance, and this is not all too easy. This being said the Akka team recently put a lot of effort in making is easier to contribute, and so my advice would be to just head to to the akka homepage and check out how to do so. Also, reading Akka source code is a lot of fun - there are many interesting pieces of code in there like "dungeons", "cells", "poison pills" and the like. Also the code quality and documentation is very high quality, you can learn a lot just by reading it. I invite you to check out the blog post series on Akka Anti-Patterns that I've been creating over the last couple months.
Check out the eBook and other resources
Reactive Web Applications teaches web developers how to benefit from the Reactive application architecture and presents hands-on examples using Play, Akka, Scala, and Reactive Streams. This book starts by laying out the fundamentals required for writing functional and asynchronous applications and quickly introduces Play as a framework to handle the plumbing of your application. The book alternates between chapters that introduce Reactive ideas (asynchronous programming with futures and actors, managing distributed state with CQRS) and practical examples that show you how to build these ideas into your applications.