Express vs. Koa Middleware

Introduction

Koa.js is a Node.js based web framework built by some of the same people behind Express.js. Koa prides itself on being a smaller, more robust, and more expressive foundation for web applications. Some of the more obvious differences between Koa and Expess include the use of generators instead of callbacks (no more callback hell!) and the fact that Koa does not come bundled with any middleware by default. In fact, Express middleware is incompatible with Koa, but there are a growing number of middleware built for Koa.

Setup

Working with Koa is very similar to working with Express. However, you will need to use a version of Node that is compatible with the Harmony flag (Node >= v0.11.13).

Normally, you would run your script via:
$ node index.js

To use Koa, you will need to run your scripts with the Harmony flag:
$ node --harmony index.js

That is all there is to it. Note that the Harmony flag also allows us to use certain ES6 features such as arrows.

Express vs Koa Middleware

We are going to set up a simple web server with Express, and then we will compare it to a simple web server written with Koa.

Express:

var app = require('express')();

app.use(function myMiddleware(req, res) {  
  res.send('Hello world.');
});

app.listen(3000, function() {  
  console.log('Server listening on localhost: ' + 3000);
});

Now the same thing with Koa:

var app = require('koa')();

app.use(function* myMiddleware() {  
  this.response.body = 'Hello world.';
});

app.listen(3000, () => {  
  console.log('Server listening on localhost: ' + 3000);
});

The first thing you may notice is the difference between Express and Koa's middleware signatures. Express middleware typically conform to the signature function funcName(req, res, ...) where the request and response objects are passed as arguments to the middleware.

Koa takes an alternate approach. Koa middleware signatures conform to function* myFunc(...). The asterisk denotes that the function is a generator. Each Koa middleware has a context which provides access to various data via the this keyword. So, this means that you can access request related data via this.request and response related data via this.response.

Another thing that you may notice is the shorthand version of an anonymous function passed as a callback to app.listen. This feature is not part of Koa, it is a feature of ES6 known as an arrow function. Arrow functions can only be used in place of anonymous functions, and they can not be generators.

Multiple Middleware

Now we will add a second layer of middleware to each of our examples.

Express:

var app = require('express')();

app.use(function myMiddleware(req, res, next) {  
  res.write('Hello world.');
  next();
});

app.use(function mySecondMiddleware(req, res) {  
  res.write('\nI am a second middleware.');
  res.end();
});

app.listen(3000, function() {  
  console.log('Server listening on localhost: ' + 3000);
});

Koa:

var app = require('koa')();

app.use(function* myMiddleware(next) {  
  this.response.body = 'Hello world.';
  yield next;
});

app.use(function* mySecondMiddleware() {  
  this.response.body += '\nI am a second middleware.';
});

app.listen(3000, () => {  
    console.log('Server listening on localhost: ' + 3000);
});

If we were to run both of these examples the end result would be the same. You may be wondering what the yield keyword in the Koa example does. I will go into how Koa middleware utilizes the yield keyword in my next post, but until then think of it as a typical function call.

Conclusion

So, we have set up basic Express and Koa examples to help us understand how each framework handles middleware. There are many similarities between Express and Koa, but overall Koa sets out to streamline and simplify the process of writing web servers with Node.

Code examples for this post can be found at CraterDust's GitHub.