中间件¶
你可以为 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
Tip
请记住,自定义专有头部可以通过 使用 'X-' 前缀 添加。
但如果你有希望浏览器客户端能够看到的自定义头部,你需要将它们添加到 CORS 配置(CORS (跨域资源共享))中,使用 expose_headers 参数,如 Starlette 的 CORS 文档 所述。
技术细节
你也可以使用 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
Tip
这里我们使用 time.perf_counter() 而不是 time.time(),因为它在这种场景下更精确。🤓
多个中间件的执行顺序¶
当你使用 @app.middleware() 装饰器或 app.add_middleware() 方法添加多个中间件时,每个新的中间件会包装应用,形成一个堆栈。最后添加的中间件是最外层的,第一个添加的是最内层的。
在请求路径上,最外层的中间件最先运行。
在响应路径上,它最后运行。
例如:
app.add_middleware(MiddlewareA)
app.add_middleware(MiddlewareB)
这会形成以下执行顺序:
-
请求: MiddlewareB → MiddlewareA → 路由
-
响应: 路由 → MiddlewareA → MiddlewareB
这种堆叠行为确保了中间件以可预测和可控的顺序执行。
其他中间件¶
你可以在高级用户指南:高级中间件中阅读更多关于其他中间件的内容。
下一节你将学习如何使用中间件处理 CORS。