如何在FastAPI中间件中获取原始响应对象?
在FastAPI中间件中获取原始响应对象的方案
要在全局中间件里获取路由返回的原始Python对象(而非序列化后的响应体),避免解析响应体带来的性能开销,你可以通过自定义全局路由类的方式实现,无需给每个路由单独加装饰器。
实现步骤
1. 自定义APIRoute类
重写APIRoute的handle方法,在FastAPI将原始返回值序列化为Response之前,把原始值存入请求的state中:
from fastapi import APIRoute, Request from starlette.responses import Response class RawResponseAPIRoute(APIRoute): async def handle(self, request: Request) -> Response: # 调用路由端点,获取原始返回值 raw_return = await self.endpoint(request) # 将原始值存入请求state,供中间件读取 request.state.raw_response = raw_return # 继续执行FastAPI的默认响应处理流程 return await super().handle(request)
2. 全局应用自定义路由类
将FastAPI应用的默认路由类替换为上面定义的类,这样所有路由都会自动使用该逻辑:
from fastapi import FastAPI app = FastAPI() # 全局设置自定义路由类 app.router.route_class = RawResponseAPIRoute @app.get("/any/route") async def make_dummy_response(): return [1,2,3]
3. 在中间件中获取原始响应
此时在中间件里,就可以通过request.state.raw_response直接拿到路由返回的原始Python对象:
@app.middleware("http") async def process_raw_response(request: Request, call_next): response = await call_next(request) # 读取原始返回值 raw_data = request.state.raw_response print(f"路由原始返回值: {raw_data}") # 输出: [1,2,3] # 这里可以对原始值做任意处理,无需解析响应体 return response
关键说明
- 这种方式跳过了响应体解析的开销,因为直接获取了路由端点返回的原始对象,没有序列化和反序列化的过程。
- 如果路由端点直接返回
Response类实例(比如JSONResponse),可以在自定义路由类里添加判断,提取响应内容(例如通过raw_return._content获取序列化后的字节流,或根据需求处理)。
内容的提问来源于stack exchange,提问作者RazDva
相关产品推荐
相关产品推荐

