© Luca Mezzalira 2018
Luca MezzaliraFront-End Reactive Architectureshttps://doi.org/10.1007/978-1-4842-3180-7_1

1. What Is Reactive Programming?

Luca Mezzalira1 
(1)
London, Surrey, UK
 

A journey of a thousand miles begins with a single step.

—Lao Tzu, Tao Te Chang

Have you ever heard about Reactive Programming or Reactive Systems? Do you think React.js is a reactive library? Have you ever thought about why you should use Rx.JS inside an Angular project? Is Rx.JS the new Loadash?

If at least one of these questions is often in your mind, this is exactly the right book to find an answer!

In these pages you will have a chance to learn more about reactive programming and reactive architecture for front-end development: a programming paradigm that is becoming more popular, every day, in the front-end community; but these days it is probably one of the most misunderstood and abused paradigm.

The main goal of this book is to provide a good understanding of what reactive programming is, how to use it in our projects, and particularly how to create fully reactive architectures for creating resilient and maintainable projects.

During this journey you will learn the following:
  • What Reactive Programming is and why it’s important

  • What are the best use cases of this programming paradigm

  • How to structure a fully Reactive architecture with different frameworks

  • What will be the future of Reactive Programming on the front-end ecosystem

If you are wondering if the concepts learned inside this book are applicable also on a back-end architecture, my answer would be YES, or at least, the majority of them could be applied to your back-end architecture too.

Bear in mind that this book will focus the attention on front-end architectures with JavaScript, but some of the concepts illustrated should be easily portable to other back-end programming languages such as Node.js, for instance.

This book assumes that you already have good understanding of JavaScript, in particular ECMAScript 6 and 7 syntax; object-oriented programming; and possibly some knowledge of functional programming, but it’s not mandatory. Let the journey begin!

What Is Reactive Programming?

Every day when we open an editor or IDE to develop a program, we use our favorite programming language; sometimes we study a new one, but, consciously or unconsciously, we are making the decision of what kind of programming paradigm we are going to work with.

Reactive programming is not a new paradigm: it’s one of the buzzwords we are used to hearing about in the JavaScript community in the past year or so, and it will become more than just a buzzword in the future.

I don’t want to begin immediately by using too many technical terms because we will have enough time to learn about them while reading this book, but it’s important that you understand what is the benefit of working in a “reactive way.

If you read blog posts or articles on the Web, few of them are going to explain reactive programming with the spreadsheet cells example, where spreadsheet cells are reacting to changes happening in other cells after user input. This is definitely a good example but we can do better than this.

I’m sure you are familiar with the dependency injection pattern where an object is injected via the constructor or in a public method exposed by a class or module. This pattern leverages several benefits like decoupling between two objects and the possibility of testing the hosting object in isolation without creating dependencies and so on.

In some programming languages when we use dependency injection we are going to define an interface as function’s argument in the hosting object and then we can interact with the methods available in the injected object.

The injected object in this case is used as an interactive object, because the host knows exactly what the contract is and how to use it.

In reactive programming instead, the hosting object will just subscribe to the injected one, and it will react to the propagation of changes during the application lifetime. See Figure 1-1 .
../images/446957_1_En_1_Chapter/446957_1_En_1_Fig1_HTML.jpg
Figure 1-1

Interactive vs. Reactive programming : in Reactive Programming the producer is A and the consumer is B

Looking at the image above, we can immediately grasp the main difference between the two approaches :
  • In the interactive example, object A is aware of which methods to call because knows exactly the B’s object contract, also if we have to understand who has affected the state of the ingested object, we will search across all the projects that we are interacting with.

  • In the reactive one, the contract is standard and object A is reacting to changes happened in object B, on top we are certain that any manipulation would occur inside the injected object; therefore we will have a stronger separation of concerns between objects.

  • Because the hosting object is reacting to any value propagated inside the object injected, our program will be up to date without the need for implementing any additional logic.

It’s time for a simple example before we move ahead with other concepts.

Let’s assume we have a class called Calculator with a method sum and a class Receipt with a method print as shown in Listing 1-1.

class Calculator {
  sum(a, b){
    return a + b;
  }
}
class Receipt {
  constructor(calculator){
    this.calc = calculator;
  }
  print(itemA, itemB){
    const total = this.calc.sum(itemA, itemB);
    console.log(`total receipt £${total}`);
  }
}
const pizza = 6.00;
const beer = 5.00;
const calc = new Calculator();
const receipt = new Receipt(calc);
receipt.print(pizza, beer);
Listing 1-1

Check Snippet1.js

As you can imagine, the program outputs “total receipt £11.”

What we are doing in this example is creating the Calculator object and a Receipt object, and then we inject the Calculator instance called calc and we call the method print from the receipt instance with few arguments.

Inside the print method we are writing in the console the total price of the elements passed.

Checking the Receipt class implementation , you can spot in the print method that we are interacting with the method sum of the Calculator class and then getting the final result.

Now let’s try to implement the same example in a reactive way in Listing 1-2.

class Calculator {
  constructor(itemA, itemB){
    const obs = Rx.Observable.of(itemA, itemB);
    const sum$ = obs.reduce((acc, item) => (acc + item));
    return {
      observable: sum$
    }
  }
}
class Receipt {
  constructor(observable$){
    observable$.subscribe(value => console.log(`total receipt: £${value}`))
  }
}
const pizza = 6.00;
const beer = 5.00;
const calc = new Calculator(pizza, beer);
const receipt = new Receipt(calc.observable);
Listing 1-2

Check Snippet2.js

As you can see in this example, the Receipt class is subscribing to an object called observable, injected via the constructor, and all the logic of how to sum the prices and propagate them is delegated to the Calculator class. Therefore, the Receipt class is just reacting to a change, happening in a certain moment of the program’s lifetime, displaying in the console the value emitted by the Calculator instance.

Another thing to highlight here is the contract between the objects: instead of knowing exactly what method we should call, we pass an, with a default contract, and we react when something changes inside it.

Overall, it’s a very simple example but I hope it helps you to understand the shift of mindset we are going to have when we work with reactive programming; in the next few chapters we will see more reactive examples like this one.

Programming Paradigms

It’s time to spend some words on programming paradigms to shed some light on reactive concepts and comparing them with functional and imperative programming.

Imperative Programming

Imperative programming is probably one of the most well-known programming paradigms.

Often, it’s the first paradigm that we learn for understanding how a computer elaborates a program: it gives us all the tools for defining implementation details in depth and specifying exactly how a program should behave step by step.

Let’s see an example of imperative programming:

class Calculator {
  constructor(){
    this.VAT = 22;
  }
  sum(...items){
    let total = 0;
    let i = 0;
    for(i; i < items.length; i++){
      total = total + items[i];
      total = total + items[i] * this.VAT/100;
    }
    return total;
  }
}
class Receipt {
  constructor(calculator){
    this.calc = calculator;
  }
  print(...items){
    let total = this.calc.sum(...items);
    console.log(`total receipt £${total.toFixed(2)}`);
  }
}
const JEANS = 80.00;
const SHIRT = 35.00;
const SHOES = 90.00;
const COAT = 140.00;
const HAT = 29.00;
const calc = new Calculator();
const receipt = new Receipt(calc);
receipt.print(JEANS, SHIRT, SHOES, COAT, HAT); //"total receipt £456.28"

Similar to the example discussed before, the sum method of the calculator object is accepting multiple arguments instead of just a couple, and we are summing all of them and applying the VAT value calculated per item.

As you can see, we are describing the exact implementation we want to perform: from defining a for statement in order to iterate trough the values in the array until expressing the VAT calculation for each single item.

Basically what we are doing is focusing on any implementation detail; potentially we could change the way we were iterating through the array’s elements and start from the last element in the array instead of the first one or use a different variable name from “i”; these are the levels of detail we usually handle with imperative programming.

Now it’s time to see how this example would be handled in functional and reactive programming.

Functional Programming

Functional programming is getting more famous on a daily base. Many languages arise embracing this paradigm and many existing languages are embracing it too for the readability, maintainability, and testability improvements.

If you are asking yourself why Functional Programming is becoming so popular, the answer can be found behind the concepts of this paradigm.

When we talk about Functional Programming we are talking about functions: in particular we are talking about pure functions.

A pure function is a function that, given an argument, is always returning the same result; it’s predictable, easy to test, and doesn’t generate any side effect inside the program.

Another important topic related to functional programming is the concept of immutability.

Immutability means that a specific value won’t ever change during its life cycle, but if we need to manipulate it, we will create a new instance that contains the manipulated version of the original object.

Even if you are not familiar with this concept or have never dealt with it, I want you to see at least one concrete example.

Usually when you are dealing with an array and you want to iterate trough the values and interact with them in an imperative programming way, you would write something like this:

const originalArray = [1, 4, 8, 12];
for(let i = 0; i < originalArray.length; i++){
  originalArray[i] = originalArray[i] + 1;
}
console.log(originalArray) //[2, 5, 9, 13]

At this stage we have completely lost the initial values of the array called originalArray; if we want to have a copy of the initial values, we would create a new array that contains the modified values and then we would check that one.

In functional programming, instead, we are working by default with immutable objects; therefore, every modification we need to apply won’t affect the original value but will generate a new one.

Taking into consideration the previous example, we could write in a functional programming way like this:

const originalArray = [1, 4, 8, 12];
const finalArray = originalArray.map(value => value+1);
console.log(finalArray); //[2, 5, 9, 13]

As you can see from these simple examples, functional programming is focused on what you are trying to achieve more than its implementation details.

That’s a fundamental distinction compared to imperative programming. In fact, with functional programming we are describing our program, focusing on each action; and we need to do describe the data flow of our program more than focusing on each single detail such as which variable we have to define for iterating an array or how to increment the variable inside the for statement.

Another important aspect of software programming is how to deal with state management .

In Object-Oriented Programming we are used to encapsulating a state inside an object and changing it via different methods described in the same object. But in functional programming we are trying to compose it via pure functions that accept as the argument a state and return a new state.

Redux ( http://redux.js.org/ ), a very well-known library in the React community, aims to resolve the problem of state management by implementing a state machine pattern.

In Redux, when we want to change the application state, we will need to call a method that accepts two arguments: the previous application state and an action. And it is returning the new state without mutating the previous one.

An Action is a simple object used for identifying in which state the application should transform.

Relying to pure functions will make our code more modular and more reusable, will create less bugs, and will suddenly become more testable!

Let’s try now to convert the previous imperative example, porting it to functional programming. See Listing 1-3.

class Calculator {
  getTotal(...items){  
    const total = items.map(::this.addVAT)
                     .reduce(this.sumElements);
    return total;
  }
  addVAT(itemValue){
    return itemValue + this.calculateVAT(itemValue);
  }
  calculateVAT(value){
    const VAT = 22;
    return value * VAT/100;
  }
  sumElements(accumulator, value){
    return accumulator + value
  }
}
class Receipt {
  print(total){
    console.log(`total receipt £${total.toFixed(2)}`);
  }
}
const JEANS = 80.00;
const SHIRT = 35.00;
const SHOES = 90.00;
const COAT = 140.00;
const HAT = 29.00;
const calc = new Calculator();
const receipt = new Receipt();
receipt.print(calc.getTotal(JEANS, SHIRT, SHOES, COAT, HAT)); // "total receipt £456.28"
Listing 1-3

Check Snippet3.js

As we can see in the sum method implementation, we are focusing more on the actions we want to implement more than how to apply them; therefore, first we know that we need to calculate the VAT value for each single element (map method) and then to sum the items for retrieving the total (reduce method).

In this implementation we don’t need to specify how we are iterating through the array elements or specifying variables to keep the state of the iteration; we just focus on our goal.

Another thing to notice in this implementation is how we are using functions as an argument of other functions; this mechanism is called high-order functions and it is another cornerstone of Functional Programming.

Obviously, Functional Programming is not just that: it is a broad topic with many other patterns to take in consideration like currying, practical application, memoization, and so on, but this is not the main topic of the book.

Bear in mind these concepts and possibly read a few posts online regarding them for mastering the different implementations because being familiar with Functional Programing will allow you to embrace Reactive Programming more easily.

If you are not used to thinking functionally, I strongly suggest peaking at a book that describes this paradigm in your favorite language; it’s a great time investment, and you won’t regret it.

Reactive Programming

We have just briefly seen Imperative and Functional Programming, but then what about Reactive Programming?

Reactive Programming is not a new concept – it’s been a while since it has been used on server-side programming – but it’s becoming very popular on the front-end ecosystem also.

We have seen how to easily turn a quick example to Reactive Programming, but it’s not just that.

With Reactive Programming we could easily transform our code to Imperative Reactive Programming or Functional Reactive Programming.

The main concept behind this paradigm is the data flow and how an object observes and reacts to changes that happened during the life cycle of an application.

Let’s start defining what Reactive Programming means :

Reactive Programming is a paradigm based on asynchronous data streams that propagate changes during the application life cycle.

What does it mean in practice? Let’s assume we have to develop a financial dashboard, and all the data are coming from a server that is aggregating them for client visualization.

For the client we need to establish a polling mechanism or open a WebSocket communication for retrieving these pieces of information, and then we need to translate them into a nice user interface that will be consumed by our users.

Trying to decompose the challenge we want to implement and how we would be reasoning without Reactive Programming, consider the following:
  1. 1.

    We need to create a proxy, an action, or a command to retrieve the data from the server every few seconds, triggering the polling mechanism.

     
  2. 2.

    After retrieving the data, we need to analyze these data, possibly modifying or analyzing them to provide a friendlier visualization.

     
  3. 3.

    Then we pass these data to different components via a mediator, store, controller, or any other layer that is coupled with a view for updating it.

     
  4. 4.

    In the last part, we would be updating the DOM from the view, maybe highlighting only the data that have been changed since the previous change (in this case, a Virtual DOM mechanism could come to rescue minimising the effort).

     

There a quite a few parts to take care and lots of events, commands, or signals to use in order to make these data flowing from different parts of our application to display them in our views.

What would you say if you knew there is a better way to do it? It’s a paradigm that will allow us to write less code and become more expressive and pluggable inside our current applications.

Obviously, I’m not saying we won’t implement all these tasks – Reactive Programming is not a silver bullet or a magic wand – but we will learn soon that this paradigm could have quite a few surprises in store regarding its simplicity and expressiveness.

Another important concept on Reactive Programming is the way we are communicating within objects .

If you remember, a few paragraphs before, I showed an example of how we could solve a simple problem of communication between objects by injecting an observable instance instead of an instance of a specific class or module.

This could lead to many interesting scenarios that are currently not fully explored in the front-end panorama.

What would you say if the contract between objects become a standard one, and the instance we inject will have a predefined contract that will allow the hosting object to subscribe to changes from the injected instance?

This is not a new concept either: a similar idea was created in 1978 with Communicating Sequential Processes (CSP) .

Despite the name, CSP allows you to work with sequential and parallel processes ; a process is not more than a “channel” used for the asynchronous communication between objects.

In this way you are decoupling the objects using a channel for the communication; this channel though will allow you to not only pass data through it but to also do the following:
  • aggregating data

  • transforming data

  • reducing data

  • decorating data

On top of that, we will be able to manipulate channels (splitting, piping, merging, and so on) for creating sophisticated interactions between objects (Figure 1-2).
../images/446957_1_En_1_Chapter/446957_1_En_1_Fig2_HTML.jpg
Figure 1-2

In this diagram we are injecting a channel to the view and the controller, presentation model, mediator, or model for allowing the update of the view when the main state changes

CSP is a fine-grained implementation of what we are going to explore in the Reactive world. If you are interested in spending some time with CSP, I’d suggest checking the library called CSP-JS ( https://github.com/ubolonton/js-csp ).

Understanding how CSP works will speed up your learning process on Reactive Programming.

After this brief digression we can move back to the main topic of this book; it’s time now to see Reactive Programming in action in association with Imperative and Functional Programming.

Let’s start with the Imperative example shown in Listing 1-4.

class Calculator {
  constructor(){
    this.VAT = 22;
  }
  sum(items){
        const items$ = Rx.Observable.from(items);
        const total$ = items$.map(value => value + (value * this.VAT/100))
                                  .reduce((acc, value) => acc + value);
    return total$;
  }
}
class Receipt {
  constructor(calculator){
    this.calc = calculator;
  }
  print(...items){
    const total$ = this.calc.sum(items);
    total$.subscribe(total => console.log(`total receipt £${total.toFixed(2)}`));
  }
}
const JEANS = 80.00;
const SHIRT = 35.00;
const SHOES = 90.00;
const COAT = 140.00;
const HAT = 29.00;
const calc = new Calculator();
const receipt = new Receipt(calc);
receipt.print(JEANS, SHIRT, SHOES, COAT, HAT);
Listing 1-4

Check Snippet4.js

In this example, we didn’t change much compared to the imperative one, but let’s analyze what we have done:
  • In the print method of the Receipt object, we have transformed the arguments to an observable.

  • We inject the observable to the sum method in the calculator class.

  • There we are first applying the VAT to each single element via the map method.

  • Then we sum these values and return another observable object.

  • Last but not least, we subscribe to the observable object returned by the sum method, and we show the total price inside the console.

At this stage, I don’t want to go in too much depth with reactive terminology; but for now think about an observable as an object that is wrapping the data and exposes some methods for manipulating the values – a sort of channel where data are flowing inside and we can apply transformation to these data.

After understanding how to implement some reactivity to Imperative Programming, let’s see how the Functional example would look like, as shown in Listing 1-5.

class Calculator {
  getTotal(...items){
    const items$ = Rx.Observable.from(items);
    const total$ = items$.map(::this.addVAT)
                     .reduce(this.sumElements);
    return total$;
  }
  addVAT(itemValue){
    return itemValue + this.calculateVAT(itemValue);
  }
  calculateVAT(value){
    const VAT = 22;
    return value * VAT/100;
  }
  sumElements(accumulator, value){
    return accumulator + value
  }
}
class Receipt {
  print(total$){
    total$.subscribe(total => console.log(`total receipt £${total.toFixed(2)}`));
  }
}
const JEANS = 80.00;
const SHIRT = 35.00;
const SHOES = 90.00;
const COAT = 140.00;
const HAT = 29.00;
const calc = new Calculator();
const receipt = new Receipt();
receipt.print(calc.getTotal(JEANS, SHIRT, SHOES, COAT, HAT));
Listing 1-5

Check Snippet5.js

Also in this case, the example is pretty much the same but now the Receipt is using the observable called total$ that got a different signature from the previous example where we got just a simple number.

Once again, an observable allows subscribing to it and retrieving the values that are flowing inside it.

At first glance these concepts could seem unimportant, but they will help us a lot when we try to create a full reactive architecture.

When Should You Use Reactive Programming?

Often, when a new trend is rising, a lot of developers are used to abusing the new technology or framework (hype-driven development). As we understood during this chapter, Reactive Programming is used for handling the propagation of data during the life cycle of an application. Therefore, a perfect fit for this paradigm would be a real-time data application like a financial dashboard or any monitoring system for instance. In a nutshell, we can say that any application that is heavily data driven could be a great fit for Reactive Programming.

Obviously, it doesn’t mean you shouldn’t use this paradigm in other applications, but real-time web apps and applications with a large amount of asynchronous transactions and mutations are where Reactive Programming really shines.

If we decide to use Reactive Programming inside existing architectures, such as Angular or Redux, for instance, it could be a good design decision because it could facilitate the update of our views or the state propagation inside components.

Nowadays the Web is full of plenty of reactive examples, libraries and frameworks are raising them with great success, and embracing them will impose a shift of mindset in order to embrace the real power of this paradigm.

Another great benefit of Reactive Programming is the simplicity of testing your code and describing data flows in a concise but clear manner.

Reactive Programming is already implemented in production environments of several large organizations such as Netflix, Google, and Microsoft.

Microsoft and Google, for instance, are a great contributor of the Reactive Programming movement ( http://reactivex.io/ ).

Netflix, as well, is another company that is contributing heavily to the evolution of this paradigm with Rx.JS 5, and Reactive Programming is applied in several implementations currently in production.

How Should You Write an Application Fully Reactive?

One night I went to a meetup in London where we were discussing the JavaScript trends for 2017. Funny enough, Reactive Programming was one of these trends and the facilitator asked a question to all of the attendees: “How many of you are working with Reactive Programming now?” And half of the room raised their hands asserting a positive answer. After this question, the facilitator asked the following one: “How many of you are using React.js only as Reactive library?” Then over 85% of the people that raised their hand at the previous question raised their hand again.

That wasn’t surprising for me because it provides an understanding how few people are interpreting Reactive Programming in a correct way.

We could decide to structure our projects with a fully Reactive architecture where the communication/interaction between objects, the state management, and the interaction with endpoints are all handled in a Reactive paradigm.

Reactive Programming on the front end and back end brought up different architectures and implementations that are interesting to use but at the same time different from what we are used to dealing with.

In this book we are going to explore different approaches currently available inside the front-end Reactive community.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.200.211