一、什么是依赖注入

依赖注入(Dependency Injection)是一种设计模式,用于管理组件之间的依赖关系。在 FastAPI 中,它用于:

  • 共享数据库连接
  • 强制执行安全性和认证
  • 参数验证
  • 代码复用

二、基础依赖

from fastapi import Depends, FastAPI

app = FastAPI()

# 简单依赖函数
def common_parameters(q: str = None, skip: int = 0, limit: int = 100):
    return {"q": q, "skip": skip, "limit": limit}

@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
    return commons

@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
    return commons

三、类作为依赖

from fastapi import Depends

class CommonQueryParams:
    def __init__(self, q: str = None, skip: int = 0, limit: int = 100):
        self.q = q
        self.skip = skip
        self.limit = limit

@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends()):
    # 自动推断依赖类型
    return {
        "q": commons.q,
        "skip": commons.skip,
        "limit": commons.limit
    }

四、多层依赖

from fastapi import Depends, HTTPException, status

# 第一层:获取 token
def get_token(token: str = Header()):
    return token

# 第二层:验证 token,依赖第一层
def verify_token(token: str = Depends(get_token)):
    if token != "secret-token":
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid token"
        )
    return token

# 第三层:获取当前用户,依赖第二层
async def get_current_user(
    token: str = Depends(verify_token),
    db: AsyncSession = Depends(get_db)
):
    # 根据 token 查询用户
    user = await get_user_by_token(db, token)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user

# 路由使用最终依赖
@app.get("/users/me")
async def read_current_user(current_user = Depends(get_current_user)):
    return current_user

五、 全局依赖

# 应用级依赖(所有路由都会执行)
app = FastAPI(dependencies=[Depends(verify_token)])

# 路由级依赖(某个路由组的所有端点)
router = APIRouter(
    prefix="/admin",
    dependencies=[Depends(verify_admin)]
)

六、yield 依赖

async def get_db():
    db = AsyncSessionLocal()
    try:
        yield db  # 使用 yield 而非 return
    finally:
        await db.close()  # 请求完成后自动清理

@app.get("/users/")
async def get_users(db: AsyncSession = Depends(get_db)):
    # db 使用完毕后会自动关闭
    return await get_all_users(db)

七、依赖缓存

from fastapi import Depends

# 默认情况下,同一个请求中多次调用同一依赖,会被缓存
async def expensive_operation():
    # 昂贵的计算
    return "result"

@app.get("/test")
async def test_endpoint(
    # 两次调用,但只执行一次
    result1 = Depends(expensive_operation),
    result2 = Depends(expensive_operation)
):
    return {"result1": result1, "result2": result2}

# 禁用缓存
@app.get("/test2")
async def test_endpoint2(
    result = Depends(expensive_operation, use_cache=False)
):
    return {"result": result}

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐