Until recently, if you wanted to create a server using functional reactive programming in Node.js or IO.js you didn’t have a lot of options. You pretty much had only one; do it yourself from scratch. Now, with the support of frhttp, you can take advantage of functional reactive programming and the large body of plugins in ExpressJS both at the same time!

What is FRP anyway?

If you’re not very familiar with FRP I’ll describe it briefly here. If you’re already an expert, feel free to skip on down to the next section. Functional Reactive Programming is a programming paradigm in which you compose pure functions which respond to values over time to produce pure outputs. Whew. Sound scary? It’s not as bad as it sounds. Almost everyone’s done FRP without knowing it. If you’ve ever used a spreadsheet to do calculations, congratulations, you’ve done FRP.

A spreadsheet typically contains a grid of cells. Each cell can either hold a value you enter, or a formula that takes the values of other cells as input and uses these to calculate a new value without changing the source cells (pure functions). Some of the cells used by a calculation cell may themselves be calculated (composing). If you enter a new value in one of the user input cells, the entire sheet automatically recalculates (respond to values over time) without you having to do perform additional action.

Extend this more generically (I’m being a bit loose here…FRP is far more powerful than any spreadsheet) and you have FRP, and that’s basically what we’re going to do. You can use this paradigm to rid yourself of callback hell and make debugging much much easier! That explanation is all I’m going to provide here, but if you’re interested in more details there’s lots of info online.

ExpressJS + FRP = Win

While there are many attractive aspects to FRP, there’s no denying that there are a ton of very solid middlewares written for ExpressJS/Connect with great communities behind them. Now it’s possible to have the best of both worlds. You can have the safety, testability and code reuse of FRP while still having access to that one middleware you can’t live without.

Step 1, install FRHTTP

To install frhttp, you just need npm. Navigate to your project directory and enter the following into the console:

npm install frhttp --save

Step 2, set up a route

Next, we’ll need to write a route. In your entry point file (where you define express) add the following:

var frhttp = require('frhttp').createServer();

To define a route we’ll create a new file. Let’s create a highly over-engineered ‘hello world’ route. If you want to learn about defining functional reactive routes using frhttp in detail you can read part 1, part 2, and part 3 of my series on doing so. Create a file called hello.world.route.js and copy the following into it.

'use strict'; function defineRoute(server) {

server.GET('/hello').onValue(function (route) {

route.when({

name: 'hello_world',

params: [],

produces: ['message'],

fn: function (produce, input) {

produce.value('message', 'hello, world!');

produce.done();

}

}).render({

params: ['message'],

fn: function (writer, input) {

writer.writeBody(input.message);

}

}

);

}); module.exports = defineRoute;

Back in the file where you added the require line for frhttp, add the following line after the declaration of frhttp to add the route to the server:

require('hello.world.route.js')(frhttp);

Step 3, integrate with Express

Integrating with Express is almost as easy as step 1. Just add the following (assuming your Express variable is called app):

app.get('/hello', function (req, res) {

frhttp.runRoute(req, res);

});

That’s it, one extra line!

[Edit: Redditor jcready pointed out that you could just pass the frhttp.runRoute as the function parameter to the get function. Totally true ☺]

If you need more control over the exact route that gets executed or you need to add variables to your frhttp route you can take a look at the integration instructions on the frhttp wiki.

You can find much more detail about frhttp on GitHub. You can also find detailed usage docs on the wiki.