中间件¶
您可以为 FastAPI 应用程序添加中间件。
“中间件”是一个在任何特定路径操作处理之前,与每个请求协同工作的函数。同时,它也是在返回每个响应之前与之协同工作的函数。
- 它接收进入应用程序的每个请求。
- 然后它可以对该请求执行某些操作或运行任何必要的代码。
- 然后它将请求传递给应用程序的其余部分(由某个路径操作)进行处理。
- 然后它接收应用程序(由某个路径操作)生成的响应。
- 然后它可以对该响应执行某些操作或运行任何必要的代码。
- 然后它返回响应。
创建中间件¶
要创建中间件,您需要在函数上方使用装饰器 @app.middleware("http")。
中间件函数接收
request。- 一个名为
call_next的函数,它将接收request作为参数。- 此函数会将
request传递给相应的路径操作。 - 然后它返回相应路径操作生成的
response。
- 此函数会将
- 然后您可以进一步修改
response,然后再返回它。
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.perf_counter()
response = await call_next(request)
process_time = time.perf_counter() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
提示
请记住,可以使用 X- 前缀 添加自定义专有标头。
但是,如果您有想要客户端在浏览器中看到自定义标头,则需要将它们添加到 CORS 配置中(CORS (跨源资源共享)),使用 Starlette 的 CORS 文档 中记录的 expose_headers 参数。
技术细节
您也可以使用 from starlette.requests import Request。
FastAPI 为您,开发者,提供了便利。但它直接来自 Starlette。
在 `response` 之前和之后¶
您可以在路径操作收到之前,为 request 添加要在其上运行的代码。
也可以在 response 生成后,返回之前添加代码。
例如,您可以添加一个自定义标头 X-Process-Time,其中包含处理请求和生成响应所花费的秒数。
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.perf_counter()
response = await call_next(request)
process_time = time.perf_counter() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
提示
这里我们使用 time.perf_counter() 而不是 time.time(),因为它对于这些用例可能更精确。 🤓
多个中间件的执行顺序¶
当您使用 @app.middleware() 装饰器或 app.add_middleware() 方法添加多个中间件时,每个新中间件都会包装应用程序,形成一个堆栈。最后添加的中间件是最外层的,第一个添加的是最内层的。
在请求路径上,最外层的中间件首先运行。
在响应路径上,它最后运行。
例如
app.add_middleware(MiddlewareA)
app.add_middleware(MiddlewareB)
这导致了以下执行顺序
-
请求:MiddlewareB → MiddlewareA → 路由
-
响应:路由 → MiddlewareA → MiddlewareB
这种堆叠行为确保了中间件以可预测且可控的顺序执行。
其他中间件¶
稍后您可以在 高级用户指南:高级中间件 中阅读有关其他中间件的内容。
您将在下一节中阅读如何使用中间件处理 CORS。