Filter过滤器

针对maty内部的request/response handler的一个前置中间件,称为过滤器。

在第一章简介中有个工作流程图,maty内部核心是分为request、response两个处理阶段。而filter过滤器的作用,就是在req/res处理阶段的前后进行一些干预动作。

干预的内容,除了业务相关,就是和ctx扩展内容相关。

一个标准的filter示例如下:

extend-router-config-filter.js
// extend router.defaultParam
app.filter('request', async (ctx, next) => {
  // before request handler

  await next(); // wait request handler

  // do it after request handler
  const { defaultParam } = ctx.router || {};

  if (defaultParam) {
    ctx.param = Object.assign({}, defaultParam, ctx.param);
    Object.assign(ctx.query, ctx.param);
    Object.assign(ctx.reqBody, ctx.param);
  }
});

该示例展示了如何定制扩展一个router配置项:defaultParam。同理可以扩展其他有需要的配置。

配置request库参数

maty内部集成request库对api接口进行请求,request库有一些配置参数,是通过ctx.httpRequestConfig 来进行设置的。httpRequestConfig必须在request handler执行前配置。

假设在api请求时,需要以下设置:

  • body请求体格式为json

  • get请求的query参数包含数组时的序列化方式

  • api接口响应超时时间为5秒

  • 自定义header头x-client:'pc'

那么可以通过以下示例实现:

request-config-filter.js
app.filter('request', async (ctx, next) => {
  // do it before request handler
  ctx.httpRequestConfig = {
    timeout: 5 * 1000, // milliseconds
    json: true,
    qsStringifyOptions: {
      arrayFormat: 'brackets'
    },
    headers: {
      'x-client': 'pc'
    }
  }

  await next();

  // after request handler
});

获取接口信息

由于api接口请求过程隐藏在maty内部,难以干预,所以提供了ctx.apiInfo扩展项,以方便某些需要。

例如,maty作为前端页面直出框架使用时,是不具备状态存储的,而往往页面可能需要用户的登录状态,这个状态只能通过api接口来获取,一般是一个接口返回的已登录token(sessionid之类)。

假设每个api接口都会在响应头添加 x-token: xxxx 来跟踪用户登录状态,在响应到浏览器前,通过ctx.apiInfo来读取这个响应头,并写入cookie,以达到在浏览器端通过coolie跟踪用户状态的目的。

那么可以通过filter response来解决,示例如下:

login-status-filter.js
app.filter('response', async (ctx, next) => {
  // before response handler

  await next(); // response handler

  // do it after response handler
  Object.keys(ctx.apiInfo).map(name => {
    const info = apiInfo[name];
    // logger
    console.info(info.method, info.api, `${info.consumeTime}ms`);

    const isLoginApi = info.api.includes('/api/login');
    if (isLoginApi) {
      const headers = info.headers;
      const token = headers['x-token'];

      ctx.cookies.set('token', token);
    }
  });
});

filter更多用法可以在实际使用中探索。

Last updated