跳到内容

中间件

你可以向 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

提示

请记住,自定义专有标头可以使用 “X-”前缀 添加。

但是,如果你有希望浏览器客户端能够看到的自定义标头,你需要使用在 Starlette 的 CORS 文档 中记载的参数 expose_headers,将它们添加到你的 CORS 配置中(CORS(跨域资源共享))。

技术细节

你也可以使用 from starlette.requests import Request

FastAPI 为了方便开发者而提供它。但它直接来自 Starlette。

response 之前和之后

你可以添加代码,使其在任何路径操作接收 request 之前与 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 → route

  • 响应: route → MiddlewareA → MiddlewareB

这种堆叠行为确保了中间件以可预测和可控的顺序执行。

其他中间件

你可以在 高级用户指南:高级中间件 中阅读更多关于其他中间件的信息。

在下一节中,你将读到如何使用中间件处理 CORS