In my last two blog entries, I’ve given an introduction to reactive programming and RxJava. In this third and final part I will show how you can convert a traditional web application to a reactive one.

All the code will be available at, there will also be the instructions of how to run the application. To get a full insight, I suggest you read the code. The final version is merged to the master branch, and the original version is found on before_rxjava branch.

The application architecture

The application consists of three parts; the third-party API, the backend and the client. The third-party API’s will stay the same, and represent an external API that we don’t have control over. The backend and the client is where we will make the changes to convert a traditional server/client application to a responsive web application. But first, let me explain the traditional web application.

The legacy application architecture

The architecture and the flow of the application is explained in the image below.

It works like this; the client calls the backend, which then makes two calls to each third part API. One call for fetching all possible destinations for an airline for the given source, and thereafter it fetches all flights for each destination. All is done synchronously, which means it will first fetch the data from the EasyJetAPI, and not until it has fetched all the data for that API it will continue to the next one. When fetched all the data from the three different APIs, it will return all the flights in one big JSON response that will be processed and rendered by the client.

Converting to a reactive architecture

To change the web application to a reactive application, we first need to convert the response from the API to an Observable instead. This is easily done by creating an Observable from the response we got from the API, like this:

Observable result = Observable.fromArray(restTemplate.getForObject(encodeURI("http://localhost:10002/easyjet/api/destinations/{from}", from),DestinationDTO[].class));

The next step is to use the new Observable when fetching the data, for example before we did the following:

List possibleEasyJetDestinations = easyJetService.getDestinations(from);

for (DestinationDTO dest : possibleEasyJetDestinations) {
List tmpFlights = easyJetService.getFlights(from, dest.getTo()); -> f.setAirline("EasyJet"));

Now we can use the power of Observables and first fetch the destinations and then use the flatMap operator to fetch the flights. The subscibeOn method tells the Observable that we want to run this operation in another thread than the main thread. The advantage of doing this, is that each of these services will run in parallel (asynchronously), instead of after each other (synchronously).

.flatMap(dest -> easyJetService.getFlights(from, dest.getTo()))
.map(f -> new FlightDTO(f.getFrom(), f.getDestination(), f.getDeparture(), f.getArrival(), f.getPrice(), "EasyJet"))

And now that each service is returning an Observable, we can use merge to join the three Observables that we got from the three different services (one for each external API).

As a last step, we change the FlightsController from returning the response as one big JSON, to instead take the advantage of Server-sent Events (SSE). SSE is a HTML5 standard, where updates or small chunks of data is push to the client. In our case we are sending each FlightDTO as an update to the client. This means that the client doesn’t need to wait for the whole response before it can start rendering the data. Instead it can start render as soon as it receives the first FlightDTO object. The support for SSE is built in Spring Boot, and is supported by most web browsers.

SseEmitter sseEmitter = new SseEmitter();
airlineService.getPossibleDestinations(from).subscribe(a -> {

return sseEmitter;

I will not explain the client part, but do take a look at the code at Gitlab. The client application is based on Angular 4 and uses RxJS.


So, what are the advantages of using RxJava? The big advantage is that we will get a more reactive application, where the data is displayed to the user in a much faster way. We were also able to divide the execution of the code into different threads, and in that way, make the code less synchronously (and almost three times faster). Of course, we could also have done this with the legacy application, but that wouldn’t be as easy.

And furthermore – even though it’s my very personal opinion – the code becomes much more readable.

Read pt #1, The Introduction, here, and pt #2, The Framework, here.