跳到正文
为什么这次写接口我选 FastAPI,不是 Flask
为什么这次写接口我选 FastAPI,不是 Flask

为什么这次写接口我选 FastAPI,不是 Flask

Web 框架一搜一大把。Flask 我写过小工具,Django 用 DRF 做过完整 REST API,这次却选了 FastAPI。这篇不讲怎么用,讲我为什么在这个节点选它、它和 Flask 的取舍差在哪。

速读#

这篇不是 FastAPI 教程,而是解释为什么在“快速写规整接口”这个阶段,我选 FastAPI 而不是 Flask。核心判断是自由和定型的取舍:Flask 给自由,FastAPI 用类型注解把接口定义、参数校验和自动文档提前固定下来。

打动我的点:一份注解管三处#

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}

启动后打开 /docs,Swagger UI 自动生成能直接点按钮测的交互文档。第一次见,真心惊艳。

靠的是类型注解:item_id: int 既做参数校验(非数字 → 422),又生成文档字段类型。一份注解,三处受益(定义、校验、文档)。

请求体是同一套逻辑,换成 Pydantic 模型:

class Item(BaseModel):
name: str
price: float
@app.post("/items")
def create_item(item: Item):
return item

字段缺了、类型不对,根本进不了我的函数——FastAPI 在门口就用 422 拦下,并告诉调用方错在哪个字段。校验失败的处理代码,我一行都没写。

文档也不止 Swagger UI 一个壳:/redoc 是另一份阅读视图,背后是同一份 OpenAPI JSON——前端可以拿它直接生成调用代码。文档不再是写完接口后补的作业,而是接口定义的副产品——路径、参数、类型、必填与否这些形状层面的信息想脱节都脱节不了,能过期的只剩手写的那部分描述文字。

FastAPI vs Flask#

FlaskFastAPI
校验 / 文档额外自己补从类型注解派生
气质自由组装接口该有的样子已定型
我何时选自由度极高的小服务快速写一堆规整接口

Flask 灵活,代价是「接口该有的规矩」全压在自己手上。Flask 生态当然也能凑出同样的东西——marshmallow 做校验、flasgger 出文档——但那是三件事各自选型、各自维护、各自可能脱节;FastAPI 里它们是同一份注解的三个输出。把类型注解当单一事实源,契约就不会散架。

定型也有代价,这不是稻草人:原型期字段变动频繁,每改一个字段都要动模型定义;确实存在要透传任意 JSON 的场景,硬套模型反而别扭。Flask 的自由在这些场景是真实价值。所以那个问句才成立——要自由还是要定型,是场景在回答,不是框架在比高下。

顺带交代一句:FastAPI 常被拿来说的还有 async 性能,但那不是我这个节点的理由。我的接口量级离「瓶颈在框架」远得很——为还不存在的流量挑性能,等于把选型理由让给宣传页。

没有绝对更好。问自己:这个场景要的是自由,还是定型?答案不同,选的就不同。

小取舍#

Terminal window
pip install fastapi "uvicorn[standard]"
# 开发
uvicorn main:app --reload
# 生产:不要 --reload;[standard] 带上性能依赖
场景选择
本地试可以不加 [standard]
生产加上;且去掉 --reload

开发态要轻,生产态要稳——同一套东西,环境不同选择不同。

第一个接口从零跑到浏览器里看到自己的 JSON,反馈感很强。但这篇真正想留的是取舍框架:

选框架先问:我这个场景要的是自由还是定型。

版权许可

CC BY-NC-SA 4.0 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

相关文章

s1oopX

登录 s1oopX