跳转至

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 返回给用户,错误信息是否友好?