FastAPI系列-11-中间件与依赖注入的区别
中间件与依赖注入的核心区别在于触发时机和可见范围:中间件作用于整个ASGI调用栈,在路由匹配前即执行,覆盖所有请求(包括404和异常),适合协议级的全站横切需求(如访问日志、CORS、请求ID);依赖注入仅在路由匹配成功后解析,仅对特定端点生效,适合业务级复用(如分页、当前用户、数据库会话)。选型遵循三条原则:协议级需求走中间件,业务级需求走依赖,跨层数据通过`request.scope`传递以保持两者职责分离。两者并非替代而是协作关系,中间件提供请求维度,依赖提供业务维度。
2026-06-24
|
12
|
0
|
0
FastAPI系列-11-中间件与依赖注入的区别
FastAPI系列-10-依赖注入
FastAPI 通过依赖注入实现上下文解析与业务逻辑的解耦。处理函数在签名中用 `Depends` 声明“需要什么”,框架启动时构建依赖图,请求时按拓扑序解析并注入结果,无需关心资源构造细节。`yield` 依赖形态将资源生命周期分为两段:`yield` 之前准备资源并注入,响应返回后自动执行 `yield` 之后的清理逻辑,框架借助 `AsyncExitStack` 保证即使处理函数异常也能完成回收。依赖支持嵌套,子依赖结果可在同一请求内缓存复用,避免重复解析。该机制旨在实现声明式协作为 IDE 和文档提供精确信息,以及便于通过 `dependency_overrides` 进行测试替换。实践上,`yield` 之后仅做资源关闭等轻量收尾,嵌套层数宜控制在三层以内,以保持可维护性。
2026-06-23
|
14
|
0
|
0
FastAPI系列-10-依赖注入
FastAPI系列-09-中间件
FastAPI 中间件遵循 ASGI 洋葱模型,请求按注册顺序先穿过所有中间件再进入路由,响应逆序返回。`@app.middleware("http")` 支持 `async def` 和 `def` 两种形态:`async def` 在事件循环内 `await call_next`,适合需读请求体或异步 I/O;`def` 被 Starlette 投递至线程池执行,适合纯计算,如生成请求 ID。注册顺序即为执行顺序,最先注册者离客户端最近,因此耗时统计中间件应排在最前以覆盖全部处理时间。典型设计是外层异步中间件读取 body 并计算耗时,写入 `X-Duration-ms` 等响应头;内层纯计算中间件生成唯一 ID 挂载到 `request.state` 和 `X-Request-ID`。实现需注意:`await request.body()` 会消耗请求体但 Starlette 缓存可重复读取,不适用于大文件上传;`def` 中间件不应包含同步阻塞调用;中间件数量应保持克制。
2026-06-22
|
20
|
0
|
0
FastAPI系列-09-中间件
FastAPI系列-08-异常处理
FastAPI 通过全局异常处理机制分离异常抛出与响应构造,避免每个路由处理器重复编写 try/except。异常沿异步栈冒泡,框架根据方法解析顺序匹配最具体的处理器,支持装饰器或字典两种注册方式,最终合并到同一个分派链。处理器函数可以是 `def` 或 `async def`,框架自动调度。核心实践是将 `HTTPException` 及其它业务异常直接抛出,在全局处理器中统一转换为一致的 JSON 结构。尤其针对 SQLAlchemy 的 `IntegrityError`,通过解析 `exc.orig.args[0]` 获取 MySQL 错误码,精确映射为 409、422 等 HTTP 状态码,使数据层无需捕获异常,错误响应的格式和状态码在整个应用中保持一致。
2026-06-21
|
24
|
0
|
0
FastAPI系列-08-异常处理
FastAPI系列-07-自定义响应数据格式
FastAPI 默认的 JSON 响应能满足多数场景,但在需要固定响应外壳或提升序列化吞吐时,可直接返回 `JSONResponse` 或更快的 `ORJSONResponse`。显式使用响应类会绕过 `response_model` 的校验与过滤,开发者需自行确保数据安全。响应类的选择(标准库编码 vs. `orjson` 编码)与 handler 的函数形态(`async def` 取决于 I/O 操作)完全正交,可自由组合。`ORJSONResponse` 通常更快,但性能收益需结合实际瓶颈评估;若查询延迟占比高,更换编码器收效甚微。ORM 中设置 `expire_on_commit=False` 可保留已加载属性,避免序列化时触发额外查询,但关联字段仍需在查询时显式预加载。面对大数据响应,最终优化方向应从更快编码转向分页或流式传输。
2026-06-20
|
16
|
0
|
0
FastAPI系列-07-自定义响应数据格式
FastAPI系列-06-请求与响应
FastAPI 通过 Pydantic 模型分别为请求与响应定义独立的契约,不共用同一套模型。请求模型(如 BookCreate)只包含客户端可写字段,过滤掉 id 等由服务端生成的属性;响应模型(如 BookOut)只暴露可读字段,防止数据库内部列外泄。框架内部有两条独立管线:请求体先经请求模型校验,通过后进入 handler;handler 返回的数据再经由 `response_model` 强制校验与字段过滤,最终序列化为 JSON。Pydantic v2 通过 `from_attributes=True` 可直接从 ORM 实例读取属性,避免手动转换。使用中需注意:列表接口宜用轻量摘要模型,序列化阶段须确保关联字段已加载以防 N+1 查询,同时应显式声明 `response_model` 而非仅靠返回类型注解,以确保字段过滤生效。
2026-06-18
|
12
|
0
|
0
FastAPI系列-06-请求与响应
FastAPI系列-05-参数分类
FastAPI通过路径模板匹配、类型推断和显式标记三层规则决定参数来源:路径中的变量归为`Path`,标量类型默认为`Query`,Pydantic模型则推断为`Body`。使用`Annotated`可将类型与约束统一声明,提升可读性。无论数据来自何处,所有参数最终都汇入同一套类型转换与校验流水线,校验失败会立即返回422响应。参数的分类与Handler采用`async def`还是`def`形态无关,后者仅取决于函数体内是否存在可`await`的I/O操作。实践上,需注意区分框架自动校验与业务校验的语义,并对字符串查询参数设置`max_length`以保障安全。
2026-06-16
|
24
|
0
|
0
FastAPI系列-05-参数分类
FastAPI系列-04-路由
随着接口数量增长,所有端点集中在一个文件会导致代码导航困难和文档混乱。FastAPI 提供 `APIRouter` 作为“迷你应用”,可按业务域独立管理端点,并通过 `prefix` 统一路径前缀、`tags` 进行 OpenAPI 文档分组,最后像拼乐高一样挂载到主应用上。 路由注册时,端点被拷贝进应用路由表。请求处理时,框架根据处理函数的形态自动分流:`async def` 函数留在事件循环内 `await`,适用于数据库、网络等 I/O 操作;`def` 函数则被投递到线程池执行,适合纯 CPU 计算。选型的关键在于函数体是否包含需要让出控制权的 `await` 调用,而不是性能优劣。错误搭配(如在 `async def` 中调用同步阻塞库)会卡死事件循环,影响并发能力。
2026-06-15
|
15
|
0
|
0
FastAPI系列-04-路由
FastAPI系列-03-同步与异步
FastAPI 中 `async def` 与 `def` 的选型核心依据是:**函数体内是否存在可 `await` 的 I/O 操作**。若所有 I/O 均有异步版本(如异步数据库驱动、`httpx`),首选 `async def` + `await`,事件循环能在单请求内并发调度,吞吐最优。若必须调用无异步版的同步阻塞库(如 `requests`、某些 PDF/加密 SDK)或进行纯 CPU 计算,则使用 `def`,框架会通过 `anyio.to_thread.run_sync` 自动将整个 handler 投递进线程池执行,保证主事件循环不阻塞。混合场景下,`async def` 主体中若仅局部存在同步阻塞调用,可使用 `await run_in_threadpool(blocking_func, ...)` 精准将此次调用抛入线程池,实现异步与同步的安全嫁接。需注意:不可在协程内直接调用同步阻塞库,否则会导致事件循环卡死;纯 CPU 操作虽入线程池,但受 GIL 限制并无真正并行加速,大规模计算应转向进程池。
2026-06-12
|
16
|
0
|
0
FastAPI系列-03-同步与异步
FastAPI系列-02-项目结构
本文介绍FastAPI项目从单文件向工程化分层目录的演化方法,核心是将职责拆分为接口层、业务层、数据访问层和ORM模型层,并遵循单向依赖原则。接口层定义路由并调用业务层;业务层编排用例,不感知HTTP;数据访问层仅封装数据库操作,不依赖上层。文章给出了`backend/`目录模板,说明各模块职责,并演示了如何将端点拆分至相应目录、通过`include_router`挂载。分层设计提升了可测性与可替换性,便于独立修改与测试。文章还指出应避免循环导入、不将ORM对象直接暴露给接口层,以及将启动操作放入`lifespan`等实践要点。
2026-06-07
|
27
|
0
|
0
FastAPI系列-02-项目结构