【FastAPI】 依赖注入 + 中间件详解

张开发
2026/4/11 6:16:50 15 分钟阅读

分享文章

【FastAPI】 依赖注入 + 中间件详解
FastAPI 依赖注入 中间件详解完整技术文档本文基于你提供的代码与注释系统化、结构化、深入原理地讲解 FastAPI 的两个核心机制依赖注入 中间件一、依赖注入系统让代码更具复用性核心思想将“通用功能”抽象为“可重用的组件”由 FastAPI 自动注入到路径操作函数中。什么是依赖注入定义依赖注入Dependency Injection, DI是一种设计模式用于将对象的依赖关系外部化由框架如 FastAPI在运行时自动提供。好处避免代码重复提高模块化与可维护性易于测试、扩展与复用举例分页参数skip和limit在多个接口中都用到可以用依赖项统一管理。依赖注入的三大步骤步骤操作说明1. 创建依赖项定义函数或类实现公共逻辑如分页、认证、数据库会话2. 导入Dependsfrom fastapi import Depends启用依赖注射系统3. 声明依赖项使用Depends(函数名)注入到路径操作函数参数中实战分页参数依赖项通用逻辑复用fromfastapiimportDepends,FastAPI,Query# 1. 创建依赖项提取通用逻辑asyncdefcommon_parameters(skip:intQuery(0,ge0,description跳过多少条),limit:intQuery(10,le100,description返回条数上限)):return{skip:skip,limit:limit}appFastAPI()# 3. 声明依赖项在路径操作函数中使用app.get(/news/news_list)asyncdefget_news_list(commons:dictDepends(common_parameters)):returncommonsapp.get(/users/users_list)asyncdefget_users_list(commons:dictDepends(common_parameters)):returncommonsapp.get(/products/product_list)asyncdefget_product_list(commons:dictDepends(common_parameters)):returncommons客户端请求示例GET /news/news_list?skip20limit5返回结果{skip:20,limit:5}执行流程图必看客户端请求 → FastAPI 路由匹配 → 检测到 Depends(common_parameters) ↓ 调用 common_parameters(skip20, limit5) → 返回字典 ↓ 注入到 commons 参数 ↓ 执行 get_news_list() → 返回数据 ↓ 响应返回客户端依赖注入的本质自动注入 类型推断FastAPI 会自动根据函数参数的类型注解来决定如何注入。例如request: Request、db: AsyncSession、commons: dict框架会自动填入对应对象。双向一体化参数定义 类型提示 自动注入重要提醒依赖项必须是可调用对象函数或类__call__方法依赖项可以是异步函数async def依赖项可以返回任意类型dict、model、session 等最佳实践建议建议说明使用Query()设置校验规则如ge0、le100防止非法参数使用description提供 API 文档说明自动生成 Swagger 文档提升可读性优先使用Pydantic模型作为依赖项更安全、更结构化如BookCreate依赖项应无副作用不应修改全局状态或执行耗时操作支持缓存的依赖项如session、cache、auth_user可声明为全局依赖二、中间件Middleware全局拦截器核心思想在请求进入路由前、响应返回客户端前插入预处理与后处理逻辑。中间件的作用作用说明日志记录记录请求 URL、IP、耗时身份认证检查 Token 是否有效请求/响应过滤改写 Header、Body、状态码错误处理捕获异常返回统一错误码性能分析统计 API 响应时间缓存控制检查是否可缓存返回缓存数据中间件的调用机制客户端 → 中间件1请求 → 中间件2请求 → 路由函数 → 中间件2响应 → 中间件1响应 → 客户端执行顺序从上往下进入 → 从下往上返回实战定义两个中间件fromfastapiimportFastAPI,Request appFastAPI()app.middleware(http)asyncdefmiddleware1(request:Request,call_next):print( 请求进入中间件1开始)# 执行前responseawaitcall_next(request)# 调用下一个处理print( 响应进入中间件1结束)returnresponseapp.middleware(http)asyncdefmiddleware2(request:Request,call_next):print( 请求进入中间件2开始)responseawaitcall_next(request)print( 响应进入中间件2结束)returnresponseapp.get(/)asyncdefroot():return{message:Hello World}访问http://localhost:8000控制台输出 请求进入中间件1开始 请求进入中间件2开始 响应进入中间件2结束 响应进入中间件1结束执行顺序1 → 2 → 路由 → 2 → 1关键术语解释术语说明request: RequestFastAPI 的请求对象包含 headers、path、cookies 等信息call_next(request)继续执行下一个中间件或路由函数response由call_next返回的响应对象可被修改后返回中间件的最佳实践建议说明使用async def定义中间件因为 FastAPI 是异步框架优先使用await call_next(request)否则不会进入路由避免阻塞操作如同步 I/O否则影响并发量把日志/认证放到中间件里便于统一管理核心逻辑不要放进中间件中间件应专注“拦截”而非“业务逻辑”

更多文章