后端中间件的用法

2018-11-20 13:12:32

灵活应用中间件机制,可以有效扩展架构的功能。中间件主要的作用有:拦截重整注入

  1. 拦截:比如通过中间件判断用户权限,如果没有权限则中止后续执行
  2. 重整:比如通过中间件对前端发来的数据进行验证,并转化为期望的类型
  3. 注入:比如通过中间件向ctx注入对象,以便为后续代码提供必要的基础功能

在这里,我们通过一个虚拟的需求,用中间件实现拦截重整注入三种功能:

  1. 沿用前面的代码,前端向后端发送两个参数:message、markCount
  2. 拦截:中间件判断message是否为空,如果为空则中止后续执行
  3. 重整:将markCount类型强制转换为Integer类型
  4. 注入:注入一个方法,以便在后续代码中调用

声明中间件

src/module/test-todo/backend/src/config/config.js

// middlewares
config.middlewares = {
  middlewareDemo: {
    global: false,
    dependencies: 'instance',
  },
};
名称 说明
global 是否为全局中间件,全局中间价会自动加载,局部中间件需要手动指定
dependencies 标明此中间件依赖哪些中间件,从而在那些中间件后面加载。一般要依赖于instance,因为instance提供了多实例的基础逻辑

定义中间件

src/module/test-todo/backend/src/config/middleware/demo.js

module.exports = options => {
  return async function middlewareDemo(ctx, next) {
    // check message
    if (!ctx.request.body.message) ctx.throw(406);
    // adjust markCount
    ctx.request.body.markCount = parseInt(ctx.request.body.markCount);
    // inject function
    if (!ctx.meta) ctx.meta = {};
    ctx.meta._demoFunction = function() {
      const { message, markCount } = ctx.request.body;
      return `${message}${new Array(markCount + 1).join('!')}`;
    };
    // next
    await next();
  };
};

引用中间件

src/module/test-todo/backend/src/config/middlewares.js

const demo = require('./middleware/demo.js');

module.exports = {
  middlewareDemo: demo,
};

使用中间件

因为middlewareDemo是局部中间件,因此需要手动在API路由上指定

src/module/test-todo/backend/src/routes.js

// test
- { method: 'post', path: 'test/echo', controller: test, middlewares: 'transaction' },
+ { method: 'post', path: 'test/echo', controller: test, middlewares: 'transaction,middlewareDemo' },

修改后端控制器方法

async echo() {
  const res = this.ctx.meta._demoFunction();
  this.ctx.success(res);
}


评论: