Koa.js Basics

I've recently started using Koa. I'm a big fan of Express but have heard good things about Koa so thought I would take a look at it. I've created an example api as I like to learn by doing.

At first glance it is very similar to Express through the use of middleware. My setup for this type of thing is:

/server.js
/lib/app.js
/lib/middleware.js
/lib/router.js
/lib/...

server.js

This literally starts the server:


require('./lib/app').listen(process.env.PORT);

app.js

const Koa = require('koa');
const app = new Koa();
require('./middleware')(app);

module.exports = app;

middleware.js

This is the main link between the app and the functionality. I like to have my middleware in one place. This is the lynchpin for the router too.

const helmet = require('koa-helmet');
const router = require('./router');

const middleware = (app) => {

app.use(helmet());

app.use(async (ctx, next) => { const start = Date.now(); await next(); const ms = Date.now() - start; ctx.set('X-Response-Time', ${ms}ms); });

app.use(async (ctx, next) => { const start = Date.now(); await next(); const ms = Date.now() - start; console.log(${ctx.method} ${ctx.url} - ${ms}); });

app .use(router.routes()) .use(router.allowedMethods());

}

module.exports = middleware;

router.js

The think about Koa is that it is quite minimal. You have to add the components you need, in this case a router. Also like the built in router of express, you can attach routers to each other. I like to have a main router file that pulls in other routes, so depending on your use case you can modularise the logic and pull them in through a router.


const Router = require('koa-router');
const router = new Router();

router.get('/', (ctx, next) => { ctx.body = 'Hello World'; next(); });

module.exports = router;

Tests

Testing as usual

const app = require('../app');
const request = require('supertest');

describe('router: index', () => { test('should respond with hello world', async () => { const response = await request(app.listen()).get('/'); expect(response.status).toEqual(200); expect(response.text).toEqual('Hello World'); }); });