In my previous write-up - Building modular javascript applications in ES6 with React, Webpack and Babel - I’d introduced turris.js that allows simple creation of Flux and React-based modular web applications.

The only topic that I had discussed quite briefly (and haven’t really addressed in turris.js itself) was component interaction and messaging. That was more or less intentional, so that everyone can pick their own Flux implementation.

But let’s fix this now and talk about options.

Flux

I haven’t talked much about Flux architecture in my previous article, but turris.js is indeed built around it.

You can find a lot of good articles on what Flux is, how it functions, how it should be used, etc, etc. So, I won’t be going too in-depth here, but I’ll say that the main idea behind it is quite simple — unidirectional data flow.

In Flux application data always flows one and only one way. If I’d to simplify all those articles on Flux, I’d say it goes like this:

Views only shows the data and can send events only to Stores Stores only manages the data and can send events only to Views

Flux data flow diagram. Dispatcher and Action elements are supplementary.

While all other elements in all those Flux schemas are important as well, they really are just supplementary.

What this data flow means in practice is that it is extremely easy to reason about your application logic (and issues that arise during its work) even when it grows large.

I said that the others elements are supplementary, but it is one of them that’s you are going to be using most of your time while developing your application. I’m talking about Dispatcher.

Dispatcher

It is the Dispatcher that handles the events sent by Stores and Views. Or, if we were to speak in Flux terminology, handles actions dispatched. Since Flux itself is just a conceptual idea, there’s a whole lot of different implementations of it. Of course, all of them include their own Dispatchers. And it is quite important to pick the right one for your project.

The main problem I had with most of those implementations while creating turris.js is the fact that to dispatch an action or to listen to one, you actually need to have a reference to the action instance (that is usually created elsewhere). Here’s an example from Reflux.js:

As you can see, Store in this case uses direct reference to action object for both — subscription and dispatching. That works good for the typical cases when your app is just one project. Of course, you can have a shared set of actions as a separate module. But that’d mean that whenever you want to introduce new things into the app — you will have to adjust that shared module. And then there’s a problem with namespaces and similarly named actions for different components (e.g. users.save and profile.save). So, this approach works fine as long as you have on monolithic application.

But what do you use when you want to have separate independent components that can be composed into a large application on demand (say, a new app for a customer)? How do you achieve this without making components interdependent? The answer is, as I’d already mentioned in my previous article, a microservices approach.

Microservices

You’ve probably heard about microservices by now. It’s one of the hot topics now. Maybe you even use them already. If you are not familiar with them, I’d once again recommend watching fantastic talk on the topic by Fred George.

And once again, just to reiterate on the idea of microserivces:

microservices are small, independent entities communicating with each other using a common interface (e.g. messaging bus, REST, RPC, etc).

At the moment we’re talking about client-side javascript application. So, we don’t really have a luxury of choice for the interface. But luckily for us, there is an awesome library that feels like it was made specifically for this case — postal.js.

So, what’s postal.js? As the description of the project states:

Postal.js is an in-memory message bus — very loosely inspired by AMQP — written in JavaScript. Postal.js runs in the browser, or on the server using node.js. It takes the familiar “eventing-style” paradigm (of which most JavaScript developers are familiar) and extends it by providing “broker” and subscriber implementations which are more sophisticated than what you typically find in simple event emitting/aggregation.

Sounds scary, but in reality it’s quite simple — you can create named channels and use them to send messages to various topics. In the end it’s still the same event-based messaging you are used to in your regular JavaScript code. But with some additional benefits.

Here’s how typical message handling scenario looks with postal:

Pretty straightforward. But having a simple way to split your messaging into different channels is pretty crucial if you are aiming for highly modular application with a lot of reusability.

I prefer to create one channel per component, so that all messaging around one component is isolated within that channel. It’s quite easy to connect two channels or topics later on from the parent application to make the components interact.

Show me the code

But enough of text, let’s get to the fun part — code!

Here’s an example of authentication Store and interactions with it:

So, what’s the benefit of doing things this way, you might ask. Why not just import signing function directly? It’s quite simple — by defining channel with specific API you are able to swap the login at will.

Using OAuth today? Cool, just include OAuth store that will sign URLs with access token. Need to use Facebook login tomorrow? Real easy, just add that Facebook store that will sign URLs using facebook library and you’re done.

And login workflow is just one example here. By utilizing messaging based on channels and topics you can easily swap pretty much any logic you’d want (assuming it produces output with the same format of course).

Caveats

Of course, all this does not comes without some caveats.

One of the biggest caveats here is names of the channels and topics. Since we don’t want to share any code between modules to stay decoupled, we can’t share any constants that declare those names. Which means we’ll use strings. Which means that burden of choosing the correct channel and topic falls on the developer. And that means all this information should be very well documented, or you are risking your sanity. That’s actually one biggest caveat I’d encountered while using postal.js, everything else is not too much of a problem.

But while not a very big issue on it’s own, the problem with postal.js versions can bring a fair share of headaches. The issue is actually pretty simple — you need to make sure all your components and your parent application that uses them are importing the same version of postal.js. In other words — there should be only one postal.js version in your compiled code (you can use Ctrl+P in Chrome DevTools to check that).

Having two versions of postal at the same time would simply mean that components speak using two different message buses. Just keep that in mind.

Oh, and if you are going to use postal.js, I’d recommend getting acquainted with postal.diagnostics early on — will save some time in figuring out issues early on.

Bonus: adding awesomeness with Postal.js plugins

But wait, that’s not it, there’s more awesome postal stuff — it can be extended with plugins! I’m going to talk about two plugins that I’d found to be useful within my projects.

postal.request-response

First plugin I want to talk about is postal.request-response. It’s value will become obvious if we’ll go back to the example code that showed URL signing.

The problem with that code will become obvious once you’ll start doing more than one signing request at a time. What happens if two requests come simultaneously? How will the correct URL get to the correct requester? The answer is — it won’t. At least not with that old code.

One way to tackle this problem is to use topic hashes, like so:

But that’s not very nice since you’re going to have that replacement snippet all over your code. So, what’s the better way? Use request-response:

Way nicer. And you get to use promises for request handling.

postal.observe

Another, somewhat more special, postal.js plugin I want to talk about is postal.observe. It’s a plugin I made for a couple of unique use cases we’ve had in some of the projects I’m working on.

The plugin itself is pretty simple — all it does is, it take postal.js subscription and wraps it into RxJS, converting it into Rx.Observable. In practice that means you can work with a subscription as if it was a stream.

Here’s a simple code example:

If you need to know why RxJS is cool and how it might be useful to you, I’d recommend watching Async JavaScript with Reactive Extensions talk from Netflix guys.

The end

As before, you can find the example code for the application and component that include Stores made using postal.js can be found on GitHub here and here.

I hope you have found something useful in this text. And maybe you even tried turris.js. If not — give it a shot! If yes — I’d love to hear any feedback or issues you might have. And of course, pull requests are always appreciated.

That’s it for today. Now go and build something! :)