Introduction to the

Those familiar with Spring MVC should know that Spring MVC is a servlet-based code framework, which is the most traditional Web framework. Spring5 then introduced Spring WebFlux, an asynchronous IO framework based on Reaction-Netty.

Similarly, NodeJS has developed an asynchronous KOA framework from the original Express 3. Koa uses Promises and AYSNC to avoid callback hell in JS and simplify error handling.

Today we are going to introduce the excellent NodeJS framework KOA.

Koa and express

Instead of using NodeJS’s REq and RES, KOA wraps its own CTx. request and ctx.Response.

Express can be seen as an application framework for NodeJS, while KOA can be seen as an abstraction of the HTTP module for NodeJS.

Unlike Express, which offers Middleware, Routing, Templating, Sending Files, and JSONP, KOA is very simple. If you want to use Routing, Sending Files, etc., Koa’s third-party middleware can be used.

Koa is not meant to replace Express, just like Spring webFlux is not meant to replace Spring MVC. Koa just changed control flow with Promises, and avoided callback hell and provided better exception handling.

Introduction to koA usage

Koa requires Node V7.6.0 + to support ES2015 and Async Function.

Let’s look at the simplest koA application:

const Koa = require('koa');
const app = module.exports = new Koa();

app.use(async function(ctx) {
  ctx.body = 'Hello World';
});

if (!module.parent) app.listen(3000);
Copy the code

A KOA application is an object that contains several middleware components that will execute a request in a stack-like order.

The cascade relationship of middleware

Koa.use is passed in a function, which we can also call middleware.

Koa can use a number of middleware, for example:

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx, next) => {
  await next();
  console.log('log3');
});

app.use(async (ctx, next) => {
  await next();
  console.log('log2');
});

app.use(async ctx => {
  console.log('log3');
});

app.listen(3000);
Copy the code

In the example above, we called Next multiple times, and as soon as we called Next, the call chain was passed to the next middleware for processing until one of the middleware stopped calling Next.

The above code runs with output:

log1
log2
log3
Copy the code

Constructor of KOA

Let’s look at the koA constructor:

constructor(options) {
    super(a); options = options || {};this.proxy = options.proxy || false;
    this.subdomainOffset = options.subdomainOffset || 2;
    this.proxyIpHeader = options.proxyIpHeader || 'X-Forwarded-For';
    this.maxIpsCount = options.maxIpsCount || 0;
    this.env = options.env || process.env.NODE_ENV || 'development';
    if (options.keys) this.keys = options.keys;
    this.middleware = [];
    this.context = Object.create(context);
    this.request = Object.create(request);
    this.response = Object.create(response);
    // util.inspect.custom support for node 6+
    /* istanbul ignore else */
    if (util.inspect.custom) {
      this[util.inspect.custom] = this.inspect; }}Copy the code

You can see that KOA receives the following parameters:

  • App. env The default value is NODE_ENV or development
  • App. keys Keys for signing cookies

See how to use it:

app.keys = ['secret1'.'secret2'];
app.keys = new KeyGrip(['secret1'.'secret2'].'sha256');

ctx.cookies.set('name'.'jack', { signed: true });
Copy the code
  • App. proxy Whether app.proxy supports proxy
  • App. subdomainOffset specifies the level at which the subdomain starts. This parameter determines the return result of Request. Subdomains
  • App. proxyIpHeader The default value of the proxy IP header is X-Forwarded-for
  • App. maxIpsCount Maximum number of IP addresses that can be read from proxy IP header. The default value is 0, indicating no limit.

We can use it like this:

const Koa = require('koa');
const app = new Koa({ proxy: true });
Copy the code

Or use it this way:

const Koa = require('koa');
const app = new Koa();
app.proxy = true;
Copy the code

Start the HTTP server

Koa is a Web framework, and a Web framework needs to start the HTTP service. To start the HTTP service, call the Server# Listen () method in NodeJS.

In KOA, we can easily start the HTTP server using the KOa # Listen method:

const Koa = require('koa');
const app = new Koa();
app.listen(3000);
Copy the code

The code above is equivalent to:

const http = require('http');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
Copy the code

Of course you can create both HTTP and HTTPS services:

const http = require('http');
const https = require('https');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
https.createServer(app.callback()).listen(3001);
Copy the code

Custom middleware

The middleware in KOA is function with the parameter value (CTX, next). In these methods, you need to manually call next() to pass to the next middleware.

Let’s look at custom middleware:

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

app.use(responseTime);
Copy the code
  • Give middleware a name:

Although the middleware function only accepts arguments (CTX, next), I can wrap it in a Wrapper method, in which we give the middleware a name:

function logger(name) {
  return async function logger(ctx, next) {
      console.log(name);
      await next();
  };    
}
Copy the code
  • Extensions to custom middleware:

Another benefit of the wrapper creation approach above is that incoming parameters can be accessed in the custom middleware, which can then be extended based on incoming parameters.

function logger(format) {
  format = format || ':method ":url"';

  return async function (ctx, next) {
    const str = format
      .replace(':method', ctx.method)
      .replace(':url', ctx.url);

    console.log(str);

    await next();
  };
}

app.use(logger());
app.use(logger(':method :url'));
Copy the code
  • Combining multiple middleware:

In the case of multiple middleware, we can use compose to combine them:

const compose = require('koa-compose');
const Koa = require('koa');
const app = module.exports = new Koa();

// x-response-time

async function responseTime(ctx, next) {
  const start = new Date(a);await next();
  const ms = new Date() - start;
  ctx.set('X-Response-Time', ms + 'ms');
}

// logger

async function logger(ctx, next) {
  const start = new Date(a);await next();
  const ms = new Date() - start;
  if ('test'! = process.env.NODE_ENV) {console.log('%s %s - %s', ctx.method, ctx.url, ms); }}// response

async function respond(ctx, next) {
  await next();
  if ('/'! = ctx.url)return;
  ctx.body = 'Hello World';
}

// composed middleware

const all = compose([
  responseTime,
  logger,
  respond
]);

app.use(all);

if (!module.parent) app.listen(3000);
Copy the code

Exception handling

How do you do exception handling in KOA?

The general method is try catch:


app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    err.status = err.statusCode || err.status || 500;
    throwerr; }});Copy the code

Of course, you can also customize the default error handler:

app.on('error'.err= > {
  log.error('server error', err)
});
Copy the code

We can also pass in context information:

app.on('error'.(err, ctx) = > {
  log.error('server error', err, ctx)
});
Copy the code

Author: Flydean program stuff

Link to this article: www.flydean.com/koa-startup…

Source: Flydean’s blog

Welcome to pay attention to my public number: “procedures those things” the most popular interpretation, the most profound dry goods, the most concise tutorial, many you do not know the small skills you find!