You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI中如何从middleware传递对象至endpoint?

FastAPI中间件传递对象至端点的实现方案与全局变量风险分析

一、能不能实现中间件创建对象并在端点访问?

你的第一个示例代码行不通,因为myObject是中间件函数里的局部变量,端点函数read_root根本碰不到它。不过FastAPI有标准方法能实现这个需求——用Request对象的state属性。

二、正确实现方式

把请求专属的对象存在request.state里就行,每个请求的state都是独立的,不会和其他请求串数据,代码示例如下:

from fastapi import FastAPI, Request

app = FastAPI()

class MyClass:
    def __init__(self, request: Request):
        self.request = request
    
    def build_data(self, arg: str):
        return f"处理后的参数:{arg},请求路径:{self.request.url.path}"

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    # 将自定义对象存入request.state
    request.state.my_object = MyClass(request)
    response = await call_next(request)
    return response

@app.get("/")
def read_root(arg: str, request: Request):
    # 从request.state取出对象使用
    data = request.state.my_object.build_data(arg)
    return {"Hello": "World", "data": data}

注意:

  • 每个请求的request.state是隔离的,所以存在里面的MyClass实例只会属于当前请求
  • 端点函数必须声明Request参数,才能访问state里的内容

三、全局变量方式的问题

你写的全局变量示例在多请求并发时会出大问题:

  • FastAPI用的ASGI服务器(比如Uvicorn)默认会开多个进程或线程处理请求,全局的myObject是所有请求共享的
  • 当多个请求同时调用myObject.use_request(request)和build_data时,会出现线程不安全的情况:前一个请求的request还没处理完,就被后一个请求覆盖了,导致build_data拿到错误的请求数据,逻辑完全混乱
  • 这种方式绝对不能用来处理请求相关的数据,完全不适合并发场景

总结:别用全局对象存请求级数据,老老实实使用request.state传递对象才是正确做法。

内容的提问来源于stack exchange,提问作者Roman Gelembjuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 23:09:59