Skip to main content

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');
  });
});