Writting Koa middlewares

  1. Writing our own middleware
  2. In Eggjs

Basically, middlewares in Koa are just async functions, they can be injected into the app’s request and response cycle. Middlewares are an array of functions that are called one after one, allowing them to access the Koa context and make changes when necessary.

Unlike other frameworks, Koa first invoke “downstream”, then control flows back “upstream”.

When a request comes in, the first middleware is called, you can invoke the next() function manually, then the function suspends and passes control to the next middleware defined. The next one calls the one after. After there are no middleware to execute, the stack will unwind and go upstream.

If you are familiar with the browser event model, you can think any code before next() as the “capture” phase and any code after that is the “bubble” phase.

Writing our own middleware

Writing our first middleware is very simple. In this example, I am going to write a middleware that checks if the authorization request header is set.

1
2
3
4
5
6
7
8
9
10
11
async function checkToken(ctx, next) {
console.log("checkToken middleware executed");
const token = ctx.request.headers["authorization"];

if (!token) {
ctx.status = 400;
ctx.body = { success: false, error: "Token is missing" };
return;
}
await next();
}

A middleware function takes two parameters: the Koa context and the next middleware to await. In the function body, we can do whatever we like and at some point call the next() function await the next middleware. This would run the next middleware in the chain, going downstream. Once the last middleware has finished running, it starts getting back upstream, finally getting back to our middleware function. In our case, we don’t have any code after the next() callback, it does nothing. You might have noticed that we have an early return when the token is not set on the request header, in this case subsequent middleware functions will not be called.

In Eggjs

Eggjs is a framework that built on Koa.

To apply a middleware in an Egg.js project, you can register it globally in config.default.js and then use the match or ignore properties to apply it to specific routes.

  1. Create the middleware in the app/middleware directory.
1
2
3
4
5
6
7
// app/middleware/customMiddleware.js
module.exports = (options, app) => {
return async function customMiddleware(ctx, next) {
console.log("Custom middleware executed");
await next();
};
};
  1. Configure the middleware globally:

Register the middleware in config.default.js and use match or ignore to specify the routes which it should or should not apply.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// config/config.default.js
module.exports = (appInfo) => {
const config = (exports = {});

// Register the middleware globally
config.middleware = ["customMiddleware"];

// Pass options to the middleware (if needed)
config.customMiddleware = {
enable: true, // Set to false to disable the middleware
match: "/some-route", // Apply to specific route(s)
// ignore: '/ignore-route', // Alternatively, use ignore to exclude specific routes
};

return config;
};