FastAPI-依赖注入

一、什么是依赖注入

依赖注入(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}
相关推荐
2301_813599553 小时前
如何监控表空间自动扩展_DBA_DATA_FILES中的MAXBYTES分析
jvm·数据库·python
我不听你讲话3 小时前
Redis 配置与优化核心内容总结
数据库·redis·缓存
生万千欢喜心4 小时前
linux 安装 人大金仓数据库
linux·运维·数据库
m0_716430074 小时前
mysql数据库表名区分大小写吗_通过lower case table names配置
jvm·数据库·python
Wy_编程4 小时前
redis 客户端编程
数据库·redis·缓存
傻啦嘿哟4 小时前
Python多进程编程:用multiprocessing突破GIL限制
服务器·网络·数据库
看我干嘛!4 小时前
mysql主从配置一主一从
数据库·mysql
@insist1234 小时前
网络工程师-网络规划与设计(三):数据中心机房设计规范全解析
服务器·网络·数据库·网络工程师·软考·软件水平考试
2401_835956814 小时前
如何利用SQL子查询进行实时监控数据分析_性能优化
jvm·数据库·python
一只大袋鼠4 小时前
Java JDBC 封装:从原生写法到工具类封装 + 增删改查
java·开发语言·数据库·mysql