Middleware writing

According to our previous analysis, middleware usually takes the following forms:

async(ctx, next) => {.... }Copy the code

Generally speaking, middleware has its own configuration, so we summed up a general middleware writing method, we can pass in the configuration of the way to return customized middleware according to the configuration:

// Common middleware writing
module.exports = function(options) {
  // Configuration processing
  
  return aysnc (ctx, next) => {
    // Middleware logic...}}Copy the code

Usage:

app.use(middleware(options)) // Middleware (options) returns a piece of middleware
Copy the code

In addition, there is another middleware writing method. As previously analyzed, koa-compose can combine multiple middleware into one middleware, so we can also combine related middleware into a large middleware as follows:

app.use(compose([middleware1, middleware2, ...] ))Copy the code

Common Middleware

Koa is based on middleware patterns, but the framework itself does not contain any middleware. In the actual development, we can achieve the function through the combination of middleware. Common middleware in Koa is as follows:

  • Koa-router: The koA-Router implementation mechanism is similar to the implementation of Koa itself, which is divided into two phases, the initialization phase and the execution phase. The initialization phase mainly involves the registration of routes, and the execution phase is to find the matching routes, and then compose a middleware using the compose function to execute the middleware. An example:
var Koa = require('koa');
var Router = require('koa-router');

var app = new Koa();
var router = new Router();

router.get('/', (ctx, next) => {}); // Register the route

app.use(router.routes()) // Returns the composite middleware that matches the route
  .use(router.allowedMethods());
Copy the code

Interested also can see the source code, easy to understand

  • As mentioned above, Node only parses the header. After the header is parsed, node sends a Request event. Body data retrieval requires listening for data and End events on reQ (incomingMessage).
const http = require('http');

http.createServer((req , res) = >{
  console.log('request here.');
  let data = ' ';
  req.on('data',(chunk)=>{
    data += chunk;
  });
  req.on('end', () = > {console.log('data:',data);
  });
}).listen(3000.'127.0.0.1');
Copy the code

The bodyParser middleware takes body data, parses it in the desired format, and assigns the parsed data to CTx.body.

app.use(bodyParser(options));
Copy the code
  • Koa-static: Creates a server for static resource access and accesses corresponding folders and files based on the URL
  • Koa-ejs: Render server templates using EJS

More middleware refer to koa official list: https://github.com/koajs/koa/wiki

Write your own middleware

Having said so much about middleware, we’ll end this article by writing one of our own. The following example is a real – life example, partially simplified. The background of the problem is that the website is often attacked by some IP addresses, which affects the normal operation of services. Therefore, a middleware is made to filter IP addresses, and all IP addresses on the IP blacklist are rejected for further processing requests. Hopefully, this example will give you a better understanding of what middleware can do.

/* ** iplimiter: IP filtering middleware. If an IP address on the IP blacklist is returned directly, the request will not continue. ** ip_blacklist: Array, example: ['192.123.12.11'] */
module.exports = function(ip_blacklist) {
  return async (ctx, next) => {
    if(!Array.isArray(configs) && configs.length) {
      let ip = ctx.request.headers['x-real-ip'] | |' ' // Obtain the client IP address. Since nginx is used as the load balancer, the method of obtaining the IP address can be through the x-real-IP field
      if(ip && ip_blacklist.indexOf(ip) ! = =- 1) {
        await next()
      } else {
        return res.end('ip restricted')}}else {
      await next()
    }
  }
}
Copy the code

Please also pay attention to my zhihu column, Fan Fan: Zhihu column: front-end thinking