Egg: [RFC] 使用类的方式写 middleware

Created on 25 Oct 2017  ·  3Comments  ·  Source: eggjs/egg

现在 egg 的大部分代码已经改成了类的方式,这个 RFC 提议讲 middleware 改成类的方式。

middleware 主要是洋葱圈的模式,有请求有响应

module.exports = options => {
  return function* (next) {
    console.log('ctx', this);
    console.log('request');
    yield next;
    console.log('response');
  };
}

改成类的方式大概有两个方案

方案一

直接转换,将来源的 middleware 换成 invoke 方法,每次请求创建 middleware 实例,并调用 invoke 方法。

const Middleware = require('egg').Middleware

class CustomMiddleware extends Middleware {
  constructor(options) {
    super(options);
  }

  * invoke(next) {
    console.log('ctx', this.ctx);
    console.log('request');
    yield next;
    console.log('response');
  }

}
module.exports = CustomMiddleware;

方案二

拆分成两个方法,实例化的方法类似,拆分为两个方法后更容易理解洋葱圈的概念

const Middleware = require('egg').Middleware

class CustomMiddleware extends Middleware {
  constructor(options) {
    super(options);
  }

  * request() {
    console.log('ctx', this.ctx);
    console.log('request');
  }

  * response() {
    console.log('response');
  }
}
module.exports = CustomMiddleware;

对比

  • 方案一:改造成本小,next 作为入参在面向对象中有点奇怪,这个方法的概念不纯粹。
  • 方案二:改造成本大,理解需要转变,不过容易理解洋葱圈。原有中断逻辑的实现比较麻烦。

    • 比如中间件拦截并直接返回,这里 request 需要返回一个状态是否直接返回。

    • 再比如捕获内层的异常,这里 response 可以传递一个 err 参数自己处理

  • 两个方法对比原有方案都需要在请求时实例化,而原来属性处理只需要一次。
proposals

Most helpful comment

这两个方案都不太好,现在中间件就是一个异步装饰器的概念,从现状看起来,保持它是一个 function 可能还更好一点,不用为了用 class 而改方案吧。

All 3 comments

这两个方案都不太好,现在中间件就是一个异步装饰器的概念,从现状看起来,保持它是一个 function 可能还更好一点,不用为了用 class 而改方案吧。

改成 class 还是 middleware 吗?koa middlewares 本身都是 push 的 function,class 太诡异了

先关了

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yuu2lee4 picture yuu2lee4  ·  3Comments

whlsxl picture whlsxl  ·  3Comments

dizhifeng picture dizhifeng  ·  3Comments

wujianling picture wujianling  ·  3Comments

ycvcb123 picture ycvcb123  ·  3Comments