Author: ICBU Qian Hang

Write at the front: welcome to Alibaba ICBU interactive & end technology front end team column, we will share quality front end technology articles with you, welcome to pay attention to & exchange yo!

Egg.js is implemented based on Koa, and its middleware mechanism is based on the Onion model like Koa

Writing middleware

Write a middleware that prints the request time

app/middleware/cost.js

async function cost(ctx, next) {
  const now = Date.now();
  await next();
  ctx.set('X-Response-Time', `${Date.now() - now}ms`);
}
Copy the code

Middleware usually has its own configuration. To avoid using a configuration every time, egg.js has a convention for middleware configuration

  1. Middleware is stored in the app/middleware/ directory

  2. Each middleware needs to be wrapped and exported with a method that receives two parameters from the framework

  3. Options: Middleware configuration items that the framework passes app.config[middlwwareName]

  4. App: current application instance

Hence the need to wrap the middleware as written above

module.exports = (options, app) => {
  return async function cost(ctx, next) {
    const now = Date.now();
    await next();
    ctx.set('X-Response-Time', `${Date.now() - now}ms`);
  };
};
Copy the code

Middleware can add configurations that allow developers to customize response headers

module.exports = options => {
  const header = options.header || 'X-Response-Time';

  return async function cost(ctx, next) {
    const now = Date.now();
    await next();
    ctx.set(header, `${Date.now() - now}ms`);
  };
};
Copy the code

Using middleware

After writing the middleware, you need to manually mount it and use it. The following methods are supported:

Application global use

If you want middleware to take effect at the application level, you can enable middleware in the config file

// config/config.${env}.js
config.middleware = ['cost'];
config.cost = {
  header: 'egg-cost',
};
Copy the code

Cost middleware is then applied to all requests, using egg-const in the response header to output the response time

Partial Router usage

If you want the middleware to take effect on only one route, you can configure it in the route

const cost = app.middleware.cost({ header: 'egg-cost' });
app.get('/', cost, 'home.index');
Copy the code

Configuring by Rules

If you only want the routes of certain rules to take effect and it is troublesome to configure them one by one, you can use rule matching. Whether the middleware loaded by the application layer or the middleware of the framework, there are several common configuration items:

  • Enable: controls whether the middleware is enabled

  • Match: Sets that only requests that match certain rules will pass through this middleware

  • Ignore: Sets requests that comply with certain rules not to pass through this middleware

    // config/config.${env}.js config.middleware = [‘cost’]; config.cost = { enable: true, ignore: /^/api/, header: ‘egg-cost’, }

Match and ignore support the same parameters, but have opposite effects and cannot be configured simultaneously. Match and Ignore support multiple configurations

  1. String: If the parameter is a string, the url path prefix is configured. All urls prefixed with the specified string will match. You can also use string array

  2. Re: When the parameter is re, the path of the URL that meets the re verification is directly matched

  3. Function: When the argument is a function, the request context is passed to the function, and the result returned by the function (true/false) is used to determine whether a match is made

    Match (CTX) {/ / only ios devices open const reg = / iphone | the | ipod/I; return reg.test(ctx.get(‘user-agent’)); },

For more on match and Ignore configurations, see egg-path-matching

Use KOA middleware

Because the Onion model is also used, KOA middleware can be easily introduced into egg.js with simple packaging. Using koA-COMPRESS as an example, when used in KOA:

const koa = require('koa');
const compress = require('koa-compress');

const app = koa();

const options = { threshold: 2048 };
app.use(compress(options));
Copy the code

In an egg. Use js

app/middleware/compress.js

Module. exports = require('koa-compress'); // Koa-compress exposes interfaces (' (options => middleware ') and middleware requirements of the framework.Copy the code

config/config.default.js

module.exports = {
  middleware: [ 'compress' ],
  compress: {
    threshold: 2048,
  },
};
Copy the code

❤️ Thank you for seeing the end ~

Alibaba international website (ICBU, Alibaba.com) is the world’s largest cross-border trade and service platform. We have new technical challenges all the time, enough interesting challenges to satisfy all your curiosity and thirst for knowledge, and well-known foreign partners (Google & OpenSky).

If you want to come to ICBU to develop the front end with me, please send your resume to [email protected] and we will respond to your interview arrangement quickly. : -)