中间件¶
你可以为 FastAPI 应用程序添加中间件。
"中间件" 是一个函数,它在每次请求被特定的 路径操作 处理之前,以及在每次响应返回之前工作。
- 它接收你的应用程序的每一个 请求。
- 然后它可以对这个 请求 进行处理,或者执行任何需要的代码。
- 然后它将 请求 传递给应用程序的其余部分(通过某些 路径操作)。
- 然后它获取应用程序生成的 响应(通过某些 路径操作)。
- 然后它可以在返回 响应 之前对其进行处理,或者执行任何需要的代码。
- 然后它返回这个 响应。
"技术细节"
如果你有包含 yield
的依赖项,退出代码将在中间件之后运行。
如果有任何后台任务(稍后记录),它们将在所有中间件之后运行。
创建一个中间件¶
要创建一个中间件,你需要在函数上使用装饰器 @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(跨源资源共享)),使用 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
Tip
在这里,我们使用 time.perf_counter()
而不是 time.time()
,因为它在这些用例中可以更精确。🤓
其他中间件¶
你可以在 高级用户指南:高级中间件 中阅读更多关于其他中间件的内容。
你将在下一节中阅读如何使用中间件处理 CORS。