FastAPI 事后检查清单
代码写完后逐条过一遍。这些是 AI 容易忽略的常见问题。
异步陷阱
- [ ]
async def路由里有没有阻塞调用?(time.sleep、同步 HTTP 请求、同步文件读写 → 会卡死事件循环) - [ ] 如果不确定是否阻塞,是否改用了普通
def?(FastAPI 自动放线程池) - [ ] 必须在 async 路由里调同步库时,是否用了
await run_in_threadpool(sync_func, ...)? - [ ] CPU 密集型任务(计算、转码)是否交给了 ProcessPoolExecutor 或任务队列,而不是线程池?
- [ ] 线程池默认只有 40 个线程,高并发场景是否够用?
依赖注入
- [ ] 数据库级校验(资源是否存在、权限检查)是否放在了
Depends()里,而不是写在 router 函数体内? - [ ] 多个端点共用的校验逻辑是否抽成了依赖,而不是复制粘贴?
- [ ] 依赖函数是否优先用了
async def?(非 async 的依赖也会被扔进线程池) - [ ] 链式依赖是否利用了 FastAPI 的缓存机制?(同一请求内相同依赖只执行一次)
安全与文档
- [ ] 非公开 API 是否隐藏了文档?(生产环境设置
openapi_url=None) - [ ] 有没有在 Pydantic 模型里暴露了不该返回的字段?(如 password_hash)
- [ ] 是否充分利用了 Pydantic 的校验能力?(Field 约束、正则、枚举,而不是在 service 里手写 if)
数据库
- [ ] SQLModel/SQLAlchemy 模型的命名是否统一?(小写蛇形、单数形式,如
post不是posts) - [ ] datetime 字段是否用
_at后缀,date 字段是否用_date后缀? - [ ] 数据库迁移文件(Alembic)是否有描述性名称?(如
2024-08-24_add_post_tags.py) - [ ] 复杂查询是否交给了 SQL 而不是在 Python 里循环处理?
- [ ] 嵌套对象的响应是否在 SQL 里用
json_build_object聚合,而不是 Python 里手动拼?
响应
- [ ] 所有接口是否都用了
Response[T]泛型包装? - [ ]
response_model是否正确设置?(注意:FastAPI 会用 response_model 再创建一次 Pydantic 对象做校验) - [ ] 是否设置了合适的
status_code?(POST 创建用 201,DELETE 用 204 等)
错误处理
- [ ] 是否定义了模块专属异常类?(
raise PostNotFound()比raise HTTPException(404, "xxx")更清晰) - [ ] Pydantic 里的
ValueError会自动变成 ValidationError 返回给用户,错误信息是否友好?