跳转至内容
There is a version suitable for your browser's language settings. Would you like to go to the english language of the site?
主页文档

中间件

H1

中间件是一种全局的、在执行 API 之前或之后,执行任意逻辑的方式。

通常,用于配合 Meta 来检查和过滤发送给 API 的请求和响应,或用于设置 Context

一开始,你希望一个 API 只对登录之后的用户提供服务,所以,你在 API 的起始位置编写了判断用户是否登录的代码:

/src/apps/demo.ts
import { defineApi, defineApiTest } from "milkio";
export const api = defineApi({
meta: {},
async action(params: {}, context) {
const token = context.headers.get("Authorization");
if (token !== "xxxx-xxxx-xxxx-xxxx") throw reject("DEVICE_NOT_LOGIN", "这个设备上还没有登录");
// 你的后续代码..
},
});

接下来,你发现这段确保用户必须登录的逻辑,似乎许多 API 都需要,这个时候,你就可以把它编写为中间件。在你的 /src/middlewares/ 目录中,新建一个 ensure-logined-middleware.ts

/src/middlewares/ensure-logined-middleware.ts
import { defineMiddleware, reject } from "milkio";
export const ensureLoginedMiddleware = defineMiddleware({
beforeExecute: async (context) => {
const token = context.headers.get("Authorization");
if (token !== "xxxx-xxxx-xxxx-xxxx") throw reject("BUSINESS_FAIL", "这个设备上还没有登录");
},
});

我们使用了 defineMiddleware 定义了一个中间件。在里面,我们使用了一个 beforeExecute 生命周期挂钩,它会在 API 被执行之前调用,在任何生命周期挂钩中,抛出任何异常都可以中断调用。如果挂钩方法都正常执行完成,那么将继续执行下一个挂钩。

我们需要将中间件添加到 MilkioApp 中,编辑你的 /milkio.ts 文件:

/milkio.ts
import { createMilkioApp } from "milkio";
export const milkio = await createMilkioApp({
middlewares: () => [
// 你刚刚编写的中间件..
ensureLoginedMiddleware(),
],
});

middlewares 是一个函数,它返回一个数组,其中包含你要添加到 MilkioApp 的中间件。数组中越靠前的中间件,就越接近于”洋葱”的最外部。

- middlewares: () => [middlewareA, middlewareB, middlewareC]
客户端 (请求)
[ ▼ ]
(middlewareA -> beforeExecute)
[ ▼ ]
(middlewareB -> beforeExecute)
[ ▼ ]
(middlewareC -> beforeExecute)
[ ▼ ]
执行 API
[ ▼ ]
(middlewareC -> afterExecute)
[ ▼ ]
(middlewareB -> afterExecute)
[ ▼ ]
(middlewareA -> afterExecute)
[ ▼ ]
客户端 (响应)

生命周期挂钩

方法名称触发时机参数备注
bootstrap在 MilkioApp 启动时执行milkioApp仅在启动时被执行一次
afterHTTPRequest在 HTTP 请求到达之后执行headers, detail仅对于 HTTP 调用会执行
beforeExecute在 API 被真正执行之前执行context通过任何方式调用都执行
afterExecute在 API 被真正执行之后执行context, response通过任何方式调用都执行
beforeHTTPResponse在 HTTP 请求结束之前执行response, detail仅对于 HTTP 调用会执行
httpNotFound在 HTTP 请求找不到时执行detailmilkio-static 依赖这个挂钩