Web 中间件
在 2.0 版本中,Midway Hooks 支持三种形式的中间件,用来覆盖不同的使用诉求。
- 2.0 全局,对所有 Api 调用都生效
- 2.0 文件,对文件内部所有 Api 生效
- 1.0 函数,仅对该 Api 函数生效
语法
中间件仅有 next 一个参数,ctx 需要通过 useContext 获得。你也可以在中间件中使用任意的 Hooks。
Logger 中间件
import { Context } from '@midwayjs/faas';
import { useContext } from '@midwayjs/hooks';
const logger = async (next: any) => {
  const ctx = useContext<Context>();
  console.log(`<-- [${ctx.method}] ${ctx.url}`);
  const start = Date.now();
  await next();
  const cost = Date.now() - start;
  console.log(`[${ctx.method}] ${ctx.url} ${cost}ms`);
};
全局中间件
全局中间件在 configuration.ts 中定义,可以传入任何框架支持的中间件
import { hooks, createConfiguration } from '@midwayjs/hooks';
import logger from './logger';
// Global Middleware
export default createConfiguration({
  imports: [
    hooks({
      middleware: [logger],
    }),
  ],
});
文件级中间件
文件级中间件在 Api 文件中定义,通过导出 config.middleware,使得其对该文件内所有 Api 函数生效。
import { ApiConfig } from '@midwayjs/hooks';
import logger from './logger';
// File Level Middleware
export const config: ApiConfig = {
  middleware: [logger],
};
export default async (message: string) => {
  return { type: 'POST', message };
};
单函数中间件
单函数中间件即只针对单个函数生效的 Web 中间件。
在 Midway Hooks 中,可以通过 withController 来支持单函数级别的中间件。
使用函数中间件
import { withController } from '@midwayjs/hooks';
import { Context } from '@midwayjs/faas';
const logger = async (next) => {
  const ctx: Context = useContext();
  const start = Date.now();
  await next();
  const cost = Date.now() - start;
  console.log(`request ${ctx.url} cost ${cost}ms`);
};
export default withController(
  {
    middleware: [logger],
  },
  () => {
    return 'Hello Controller';
  }
);
使用 IoC 中间件
import { withController } from '@midwayjs/hooks';
import { Context } from '@midwayjs/faas';
import { Provide, ScopeEnum, Scope } from '@midwayjs/decorator';
@Provide('classMiddleware')
@Scope(ScopeEnum.Singleton)
export class ClassMiddleware {
  resolve() {
    return async (ctx: Context, next) => {
      ctx.query.from = 'classMiddleware';
      await next();
    };
  }
}
export default withController(
  {
    middleware: ['classMiddleware'],
  },
  () => {
    return 'Hello Controller ' + ctx.query.from;
  }
);
API
withController
通过 withController 增强函数功能,第一个参数是 controller 配置,第二个参数是要执行的 FaaS 函数。
其中 controller 配置如下
- middleware(any[]):可选参数,用于给当前的函数增加中间件功能,可以同时传入多个中间件。支持函数定义的中间件及 IoC 定义的中间件。
类型定义
type Controller = {
  middleware?: any[];
};
function withController(controller: Controller, func);