tachybase_todo/docs/zh-CN/api/resourcer/middleware.md
2023-02-10 16:56:40 +08:00

3.6 KiB

Middleware

与 Koa 的中间件类似,但提供了更多增强的功能,可以方便的进行更多的扩展。

中间件定义后可以在资源管理器等多处进行插入使用,由开发者自行控制调用的时机。

构造函数

签名

  • constructor(options: Function)
  • constructor(options: MiddlewareOptions)

参数

参数名 类型 默认值 描述
options Function - 中间件处理函数
options MiddlewareOptions - 中间件配置项
options.only string[] - 仅允许指定的操作
options.except string[] - 排除指定的操作
options.handler Function - 处理函数

示例

简单定义:

const middleware = new Middleware((ctx, next) => {
  await next();
});

使用相关参数:

const middleware = new Middleware({
  only: ['create', 'update'],
  async handler(ctx, next) {
    await next();
  },
});

实例方法

getHandler()

返回已经过编排的处理函数。

示例

以下中间件在请求时会先输出 1,再输出 2

const middleware = new Middleware((ctx, next) => {
  console.log(1);
  await next();
});

middleware.use(async (ctx, next) => {
  console.log(2);
  await next();
});

app.resourcer.use(middleware.getHandler());

use()

对当前中间件添加中间件函数。用于提供中间件的扩展点。示例见 getHandler()

签名

  • use(middleware: Function)

参数

参数名 类型 默认值 描述
middleware Function - 中间件处理函数

disuse()

移除当前中间件已添加的中间件函数。

签名

  • disuse(middleware: Function)

参数

参数名 类型 默认值 描述
middleware Function - 中间件处理函数

示例

以下示例在请求处理时只输出 1,不执行 fn1 中的 2 输出。

const middleware = new Middleware((ctx, next) => {
  console.log(1);
  await next();
});

async function fn1(ctx, next) {
  console.log(2);
  await next();
}

middleware.use(fn1);

app.resourcer.use(middleware.getHandler());

middleware.disuse(fn1);

canAccess()

判断当前中间件针对特定操作是否要被调用,通常由资源管理器内部处理。

签名

  • canAccess(name: string): boolean

参数

参数名 类型 默认值 描述
name string - 操作名称

其他导出

branch()

创建一个分支中间件,用于在中间件中进行分支处理。

签名

  • branch(map: { [key: string]: Function }, reducer: Function, options): Function

参数

参数名 类型 默认值 描述
map { [key: string]: Function } - 分支处理函数映射表,键名由后续计算函数在调用时给出
reducer (ctx) => string - 计算函数,用于基于上下文计算出分支的键名
options? Object - 分支配置项
options.keyNotFound? Function ctx.throw(404) 未找到键名时的处理函数
options.handlerNotSet? Function ctx.throw(404) 未定义处理函数时的处理

示例

用户验证时,根据请求 URL 中 query 部分的 authenticator 参数的值决定后续需要如何处理:

app.resourcer.use(branch({
  'password': async (ctx, next) => {
    // ...
  },
  'sms': async (ctx, next) => {
    // ...
  },
}, (ctx) => {
  return ctx.action.params.authenticator ?? 'password';
}));