第4世代Expressフレームワークkoaの概要


概要
Spring MVCに詳しい方は、Spring MVCがservletベースのコードフレームワークであることを知っているはずです.これは最も伝統的なwebフレームワークです.次にSpring 5にSpring WebFluxを導入した.これはreactive-nettyベースの非同期IOフレームワークである.
同様に,nodejsは最初のExpress 3に基づいて非同期koaフレームワークを開発した.koaはpromisesとaysncを用いてJSにおけるコールバック地獄を回避し,エラー処理を簡略化した.
今日はこの優秀なnodejsフレームワークkoaを紹介します.
koaとexpress
koaはnodejsのreqとresを使用するのではなく、自分のctxをカプセル化する.requestとctx.response.
expressはnodejsのアプリケーションフレームワークと見なすことができ、koaはnodejsのhttpモジュールの抽象と見なすことができる.
Middleware、Routing、Templating、Sending Files、JSONPなどの機能をexpressが提供しているのとは異なり、koaの機能は単一で、routing、sending filesなどの他の機能を使用したい場合は、koaのサードパーティミドルウェアを使用することができます.
koaはexpressを置き換えに来たわけではありません.spring webFluxがspring MVCを置き換えたわけではありません.koaはPromisesで制御流を書き換えただけで,コールバック地獄を回避し,より良い異常処理機構を提供した.
koaの使用紹介
koaはnode v 7を必要とする.6.0+バージョンでES 2015とasync functionをサポートします.
最も簡単なkoaアプリケーションを見てみましょう
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);

koaアプリケーションは、stackのような実行順序で対応するrequestを持つ複数のミドルウェアを含むオブジェクトです.
ミドルウェアのカスケード関係
koa.useに伝わるのはfunctionであり,ミドルウェアとも呼ばれる.
koaは多くのミドルウェアをuseすることができます.例を挙げます.
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);

上記の例では、nextを呼び出すと、あるミドルウェアがnextを呼び出さなくなるまで、呼び出しチェーンは次のミドルウェアに渡されて処理されます.
上のコードは出力を実行します.
log1
log2
log3

koaの構造関数
koaの構造関数を見てみましょう.
constructor(options) {
    super();
    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;
    }
  }

koaは次のパラメータを受信していることがわかります.
  • app.EnvデフォルトはNODE_ENVまたはdevelopment
  • app.keysはクッキーに署名したkeys
  • 使い方を見てみましょう.
    app.keys = ['secret1', 'secret2'];
    app.keys = new KeyGrip(['secret1', 'secret2'], 'sha256');
    
    ctx.cookies.set('name', 'jack', { signed: true });
  • app.Proxyがエージェント
  • をサポートしているかどうか
  • app.subdomainOffsetはサブドメイン名が何番目から始まるかを表し、このパラメータはrequestを決定する.subdomainsの戻り結果、デフォルト値は2
  • です.
  • app.proxyIpHeader proxy ip headerデフォルト値はX-Forwarded-For
  • app.maxIpsCountがproxy ip headerから読み込んだ最大ip個数で、デフォルト値は0で無制限です.

  • 次のように使用できます.
    const Koa = require('koa');
    const app = new Koa({ proxy: true });

    または、次のように使用します.
    const Koa = require('koa');
    const app = new Koa();
    app.proxy = true;

    http serverの起動
    koaはWebフレームワークであり、Webフレームワークはhttpサービスを開く必要があり、httpサービスを起動するにはnodejsのServer#listen()メソッドを呼び出す必要があります.
    koaでは、koa#listenメソッドを使用してこのhttp serverを起動するのに便利です.
    const Koa = require('koa');
    const app = new Koa();
    app.listen(3000);

    上のコードは次のとおりです.
    const http = require('http');
    const Koa = require('koa');
    const app = new Koa();
    http.createServer(app.callback()).listen(3000);

    もちろんhttpとhttpのサービスを同時に作成することができます.
    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);

    カスタムミドルウェア
    koaのミドルウェアはパラメータ値(ctx,next)のfunctionである.これらの方法では、next()を手動で呼び出して次の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);
  • ミドルウェアに名前を付けます:
  • ミドルウェアfunctionはパラメータ(ctx,next)のみを受信しますが、wrapperメソッドでパッケージできます.wrapperメソッドでは、ミドルウェアに名前を付けます.
    function logger(name) {
      return async function logger(ctx, next) {
          console.log(name);
          await next();
      };    
    }
  • カスタムミドルウェアの拡張:
  • 上記のwrapperの作成方法には、カスタムミドルウェアに転送されたパラメータにアクセスでき、転送されたパラメータに基づいてカスタムミドルウェアを拡張できるというもう一つの利点があります.
    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'));
  • 複数のミドルウェアの組み合わせ:
  • 複数のミドルウェアがある場合、composeを使用してマージできます.
    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();
      await next();
      const ms = new Date() - start;
      ctx.set('X-Response-Time', ms + 'ms');
    }
    
    // logger
    
    async function logger(ctx, next) {
      const start = new Date();
      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);

    例外処理
    koaではどのように異常処理を行いますか?
    一般的な方法はtry catchです.
    
    app.use(async (ctx, next) => {
      try {
        await next();
      } catch (err) {
        err.status = err.statusCode || err.status || 500;
        throw err;
      }
    });
    

    もちろん、デフォルトのerrorプロセッサをカスタマイズすることもできます.
    app.on('error', err => {
      log.error('server error', err)
    });

    また、コンテキスト情報を入力することもできます.
    app.on('error', (err, ctx) => {
      log.error('server error', err, ctx)
    });

    本文の作者:flydeanプログラムのあれらの事
    このリンク:http://www.flydean.com/koa-startup/
    出典:flydeanのブログ
    私の公衆番号に注目することを歓迎します:“プログラムのあれらの事”の最も通俗的な解読、最も深い乾物、最も簡潔な教程、多くのあなたの知らない小さい技巧はあなたが発見することを待っています!