35. FastAPI 依赖注入_类依赖
类也可以是可调用的依赖
调用类会创建实例,因此 FastAPI 可以解析构造函数参数,再把实例注入路由。它适合把分页、搜索等一组相关参数组织成带属性和方法的对象。
类作为参数依赖
python
from typing import Annotated
from fastapi import Depends, FastAPI, Query
app = FastAPI()
class Pagination:
def __init__(
self,
page: Annotated[int, Query(ge=1)] = 1,
size: Annotated[int, Query(ge=1, le=100)] = 20,
):
self.page = page
self.size = size
@property
def offset(self):
return (self.page - 1) * self.size
@app.get("/items")
def items(pagination: Annotated[Pagination, Depends(Pagination)]):
return {"page": pagination.page, "size": pagination.size,
"offset": pagination.offset}保存为 main.py 并启动。/items?page=3&size=5 得到 offset=10。这里 Pagination 是普通类,不是请求体模型;FastAPI 检查其构造函数参数,并照样生成查询参数文档。
可调用实例:先配置,再按请求执行
当不同接口需要同一种检查的不同配置时,可实现 __call__:
python
from fastapi import Header, HTTPException
class RequireFeature:
def __init__(self, expected: str):
self.expected = expected
def __call__(self, x_feature: Annotated[str | None, Header()] = None):
if x_feature != self.expected:
raise HTTPException(400, "缺少功能演示标识")
require_export = RequireFeature("export")
@app.get("/export", dependencies=[Depends(require_export)])
def export():
return {"message": "执行导出示例"}追加到同一 main.py,请求 /export 并带 X-Feature: export。这只是可参数化依赖示例,客户端自报功能标识不能当真实授权。
两种类用法的区别
Depends(Pagination):解析构造函数,按请求创建对象。
Depends(require_export):实例已经创建,解析并调用其 __call__。预配置实例通常跨请求共享,因此只存只读配置,不把当前用户、Session 或本次查询结果写进共享属性。
依赖实例可再声明其他 Depends,例如先获取当前用户再检查角色。清理资源时可在 __call__ 中使用 yield,并遵守与函数依赖相同的生命周期规则。
什么时候不用类
一个只返回数字的小函数没有必要包装成类;大量参数本身属于 JSON 正文时应使用 Pydantic 模型;有状态的外部客户端通常由 lifespan 负责创建与关闭,再用依赖提供引用。
练习:给 Pagination 加入 limit 属性,并让两个接口复用;再创建两个 RequireFeature 实例,分别挂载到导出与导入接口。