FastAPI 系列
FastAPI 为什么适合做 JSON API(当前篇)
很多人第一次被 FastAPI 吸引,是因为打开 /docs 就能试接口。自动文档不是魔法,它是类型提示、Pydantic 和 OpenAPI 三条链路的结果。把这三层搞混,就会既写不好校验,也看不懂为什么生产必须用 ASGI 服务器。

它站在哪一层
FastAPI 自己几乎不处理 TCP。典型调用栈是:
客户端
→ Uvicorn(ASGI 服务器)
→ FastAPI(路由、依赖、OpenAPI)
→ Starlette(ASGI 工具、中间件、WebSocket)
→ Pydantic(请求/响应数据校验)
ASGI 是异步服务网关接口,对应 WSGI 的下一代。Flask 默认走 WSGI;FastAPI 默认走 ASGI。所以生产入口是 Uvicorn 这类 ASGI 服务器,而不是 Waitress / Gunicorn 的同步 worker 单独扛请求(Gunicorn 现在更多是进程管理器角色,官方镜像路线也已改为直接用 Uvicorn workers)。
类型提示为什么是一等公民
下面这个函数不是「顺便写了类型」,类型就是接口契约:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
item_id: int 会让 FastAPI 把路径转换成整数,失败则返回 422。q: str | None = None 表示可选查询参数。这些信息同时用于:运行时校验、编辑器补全、OpenAPI schema。
Pydantic v2 负责把 JSON 变成模型实例。你声明的不是注释,是校验器。
OpenAPI 从哪来
应用启动后,FastAPI 扫描所有路径操作,生成 OpenAPI JSON,默认挂在:
/openapi.json
/docs → Swagger UI
/redoc → ReDoc
文档不是手写 Markdown 渲染出来的。你改了模型字段,文档跟着改。这也是为什么响应要用模型过滤:文档里写「不返回 password」,运行时也必须真的不返回。
async 到底快在哪
事件循环适合「等网络、等数据库」的时间。等待期间可以去处理别的请求,所以同样的线程能撑住更多 I/O 并发。
它不适合:
在
async def里调用同步requests.get或同步 ORM;长时间 CPU 计算还不丢进线程池。
官方建议:I/O 用异步库;必须调用阻塞代码时,用普通 def 路径操作,FastAPI 会把它放到线程池,避免堵住事件循环。
常见误区
FastAPI 等于 Uvicorn
FastAPI 是应用框架,Uvicorn 是服务器。本地 fastapi dev 只是帮你把两者连起来。
类型提示只给 IDE 看
在 FastAPI 里,类型提示会进入校验和 OpenAPI。写错类型,线上就会按错误契约跑。
ASGI 会自动让整个调用链异步
ASGI 只定义服务器与应用的对话方式。你的依赖、数据库驱动、HTTP 客户端都必须自己选异步实现。
小结
记住三句话:服务器是 ASGI;契约是类型;文档是 OpenAPI 的投影。下一篇把第一个应用跑起来,让这三层变成可访问的 /docs。
参考资料
FastAPI 为什么适合做 JSON API:ASGI、类型提示与自动文档
https://lautung.com/archives/fastapi-01-asgi-docs
评论