3.9 KiB
中间件
你可以向 FastAPI 应用添加中间件。
“中间件”是一个函数,它会在每个特定的路径操作处理每个请求之前运行,也会在返回每个响应之前运行。
- 它接收你的应用的每一个请求。
- 然后它可以对这个请求做一些事情或者执行任何需要的代码。
- 然后它将这个请求传递给应用程序的其他部分(某个路径操作)处理。
- 之后它获取应用程序生成的响应(由某个路径操作产生)。
- 它可以对该响应做一些事情或者执行任何需要的代码。
- 然后它返回这个响应。
/// note | 技术细节
如果你有使用 yield 的依赖,依赖中的退出代码会在中间件之后运行。
如果有任何后台任务(会在后台任务{.internal-link target=_blank}一节中介绍,你稍后会看到),它们会在所有中间件之后运行。
///
创建中间件
要创建中间件,你可以在函数的顶部使用装饰器 @app.middleware("http")。
中间件函数会接收:
request。- 一个函数
call_next,它会把request作为参数接收。- 这个函数会把
request传递给相应的路径操作。 - 然后它返回由相应路径操作生成的
response。
- 这个函数会把
- 在返回之前,你可以进一步修改
response。
{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
/// tip
请记住可以使用 X- 前缀添加专有自定义请求头。
但是如果你有希望让浏览器中的客户端可见的自定义请求头,你需要把它们加到你的 CORS 配置(CORS (Cross-Origin Resource Sharing){.internal-link target=_blank})的 expose_headers 参数中,参见 Starlette 的 CORS 文档。
///
/// note | 技术细节
你也可以使用 from starlette.requests import Request。
FastAPI 为了开发者方便提供了该对象,但它直接来自 Starlette。
///
在 response 之前与之后
你可以在任何路径操作接收 request 之前,添加要与该 request 一起运行的代码。
也可以在生成 response 之后、返回之前添加代码。
例如,你可以添加一个自定义请求头 X-Process-Time,其值为处理请求并生成响应所花费的秒数:
{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
/// tip
这里我们使用 time.perf_counter() 而不是 time.time(),因为在这类场景中它可能更精确。🤓
///
多个中间件的执行顺序
当你使用 @app.middleware() 装饰器或 app.add_middleware() 方法添加多个中间件时,每个新中间件都会包裹应用,形成一个栈。最后添加的中间件是“最外层”的,最先添加的是“最内层”的。
在请求路径上,最外层的中间件先运行。
在响应路径上,它最后运行。
例如:
app.add_middleware(MiddlewareA)
app.add_middleware(MiddlewareB)
这会产生如下执行顺序:
-
请求:MiddlewareB → MiddlewareA → 路由
-
响应:路由 → MiddlewareA → MiddlewareB
这种栈式行为确保中间件按可预测且可控的顺序执行。
其他中间件
你可以稍后在高级用户指南:高级中间件{.internal-link target=_blank}中阅读更多关于其他中间件的内容。
你将在下一节中了解如何使用中间件处理 CORS。