Fastapi

21 篇文章
FastAPI系列-10-依赖注入

FastAPI系列-10-依赖注入

FastAPI 通过依赖注入实现上下文解析与业务逻辑的解耦。处理函数在签名中用 `Depends` 声明“需要什么”,框架启动时构建依赖图,请求时按拓扑序解析并注入结果,无需关心资源构造细节。`yield` 依赖形态将资源生命周期分为两段:`yield` 之前准备资源并注入,响应返回后自动执行 `yield` 之后的清理逻辑,框架借助 `AsyncExitStack` 保证即使处理函数异常也能完成回收。依赖支持嵌套,子依赖结果可在同一请求内缓存复用,避免重复解析。该机制旨在实现声明式协作为 IDE 和文档提供精确信息,以及便于通过 `dependency_overrides` 进行测试替换。实践上,`yield` 之后仅做资源关闭等轻量收尾,嵌套层数宜控制在三层以内,以保持可维护性。

FastAPI系列-09-中间件

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` 中间件不应包含同步阻塞调用;中间件数量应保持克制。

FastAPI系列-08-异常处理

FastAPI系列-08-异常处理

FastAPI 通过全局异常处理机制分离异常抛出与响应构造,避免每个路由处理器重复编写 try/except。异常沿异步栈冒泡,框架根据方法解析顺序匹配最具体的处理器,支持装饰器或字典两种注册方式,最终合并到同一个分派链。处理器函数可以是 `def` 或 `async def`,框架自动调度。核心实践是将 `HTTPException` 及其它业务异常直接抛出,在全局处理器中统一转换为一致的 JSON 结构。尤其针对 SQLAlchemy 的 `IntegrityError`,通过解析 `exc.orig.args[0]` 获取 MySQL 错误码,精确映射为 409、422 等 HTTP 状态码,使数据层无需捕获异常,错误响应的格式和状态码在整个应用中保持一致。

FastAPI系列-07-自定义响应数据格式

FastAPI系列-07-自定义响应数据格式

FastAPI 默认的 JSON 响应能满足多数场景,但在需要固定响应外壳或提升序列化吞吐时,可直接返回 `JSONResponse` 或更快的 `ORJSONResponse`。显式使用响应类会绕过 `response_model` 的校验与过滤,开发者需自行确保数据安全。响应类的选择(标准库编码 vs. `orjson` 编码)与 handler 的函数形态(`async def` 取决于 I/O 操作)完全正交,可自由组合。`ORJSONResponse` 通常更快,但性能收益需结合实际瓶颈评估;若查询延迟占比高,更换编码器收效甚微。ORM 中设置 `expire_on_commit=False` 可保留已加载属性,避免序列化时触发额外查询,但关联字段仍需在查询时显式预加载。面对大数据响应,最终优化方向应从更快编码转向分页或流式传输。

FastAPI系列-06-请求与响应

FastAPI系列-06-请求与响应

FastAPI 通过 Pydantic 模型分别为请求与响应定义独立的契约,不共用同一套模型。请求模型(如 BookCreate)只包含客户端可写字段,过滤掉 id 等由服务端生成的属性;响应模型(如 BookOut)只暴露可读字段,防止数据库内部列外泄。框架内部有两条独立管线:请求体先经请求模型校验,通过后进入 handler;handler 返回的数据再经由 `response_model` 强制校验与字段过滤,最终序列化为 JSON。Pydantic v2 通过 `from_attributes=True` 可直接从 ORM 实例读取属性,避免手动转换。使用中需注意:列表接口宜用轻量摘要模型,序列化阶段须确保关联字段已加载以防 N+1 查询,同时应显式声明 `response_model` 而非仅靠返回类型注解,以确保字段过滤生效。

FastAPI系列-05-参数分类

FastAPI系列-05-参数分类

FastAPI通过路径模板匹配、类型推断和显式标记三层规则决定参数来源:路径中的变量归为`Path`,标量类型默认为`Query`,Pydantic模型则推断为`Body`。使用`Annotated`可将类型与约束统一声明,提升可读性。无论数据来自何处,所有参数最终都汇入同一套类型转换与校验流水线,校验失败会立即返回422响应。参数的分类与Handler采用`async def`还是`def`形态无关,后者仅取决于函数体内是否存在可`await`的I/O操作。实践上,需注意区分框架自动校验与业务校验的语义,并对字符串查询参数设置`max_length`以保障安全。

FastAPI系列-04-路由

FastAPI系列-04-路由

随着接口数量增长,所有端点集中在一个文件会导致代码导航困难和文档混乱。FastAPI 提供 `APIRouter` 作为“迷你应用”,可按业务域独立管理端点,并通过 `prefix` 统一路径前缀、`tags` 进行 OpenAPI 文档分组,最后像拼乐高一样挂载到主应用上。 路由注册时,端点被拷贝进应用路由表。请求处理时,框架根据处理函数的形态自动分流:`async def` 函数留在事件循环内 `await`,适用于数据库、网络等 I/O 操作;`def` 函数则被投递到线程池执行,适合纯 CPU 计算。选型的关键在于函数体是否包含需要让出控制权的 `await` 调用,而不是性能优劣。错误搭配(如在 `async def` 中调用同步阻塞库)会卡死事件循环,影响并发能力。

FastAPI系列-03-同步与异步

FastAPI系列-03-同步与异步

FastAPI 中 handler 用 `async def` 还是 `def`,唯一判断标准是函数体内是否存在可 `await` 的 I/O。拥有异步驱动的 I/O 操作(如 `aiomysql`、`httpx.AsyncClient`)应使用 `async def`,由事件循环并发调度;需调用同步阻塞库(如 `requests`、同步加密/PDF SDK)或纯 CPU 计算时,使用 `def`,框架会自动将函数投递到线程池执行,避免阻塞事件循环。对于主体为异步逻辑但夹杂少量同步调用的混合场景,可用 `async def` 配合 `run_in_threadpool` 将阻塞部分精准丢入线程池。注意,`async def` 中不得直接调用同步阻塞函数;`def` 的 CPU 任务仍受 GIL 限制,大量计算应走进程池或任务系统。该选择由 Starlette 在端点边界通过 `run_endpoint_function` 一次完成。

FastAPI系列-02-项目结构

FastAPI系列-02-项目结构

告别单文件,采用分层工程化目录是 FastAPI 项目规模化的关键。核心思想是将“对外协议”与“对内实现”拆分,形成单向依赖的四层结构:接口层(`app/api/`)负责路由与请求响应,数据契约层(`app/schemas/`)定义 Pydantic 模型,业务层(`app/services/`)编排业务用例,数据访问层(`app/dao/`)仅与 ORM 交互,底层为持久化模型(`app/models/`)。入口 `main.py` 只负责创建应用与注册路由。依赖方向严格由上层指向下层,禁止反向依赖,从而带来独立测试与替换的灵活性。目录中还包含配置与工具模块,并以环境变量区分环境。该架构通过将路由、业务与数据库操作物理隔离,确保代码可维护、可扩展,是团队协作与项目长期演进的坚实基础。

FastAPI系列-01-FastAPI介绍

FastAPI系列-01-FastAPI介绍

FastAPI 是一个基于 Starlette 和 Pydantic 构建的现代 Python Web 框架,专为 API 设计,核心优势在于通过 ASGI 异步协议实现高并发,利用 Pydantic v2 的 Rust 内核加速数据校验与序列化,并在启动时完成路由与依赖的预处理以降低运行时开销。其请求处理链分工明确,各层可独立替换,便于性能排查与灵活迁移。开发上,FastAPI 深度集成 Python 类型注解,能自动完成请求解析、参数校验和 OpenAPI 文档生成,显著减少代码量。使用时需注意避免同步阻塞破坏事件循环,不可滥用弱类型注解以保留自动校验能力,并应将共享资源放在 lifespan 中管理,异步栈须统一,防止混用导致问题。