Skip to content

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 实例,分别挂载到导出与导入接口。