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