FastAPI 设计溯源:从 Django、Flask 到 Starlette 的替代方案、灵感来源与架构取舍全景解读
FastAPI 并非凭空诞生,它的每一个核心特性——基于 Python type hints 的校验、自动化的 OpenAPI 文档、依赖注入、高性能 ASGI 运行时——都能在它之前的十余个框架、库与工具中找到源头。本文以官方文档 docs/hi/docs/alternatives.md(英文原文见 docs/en/docs/alternatives.md)为主线,逐一拆解 FastAPI 的"前身工具谱系"、它所借鉴的设计思想、以及它最终选择建立在 Pydantic + Starlette + Uvicorn 之上的底层原因,并结合本仓库源码给出可验证的实现证据。
引言:为什么 FastAPI 会存在
如果没有其他人此前的积累,FastAPI 就不会存在。在决定"亲手造一个框架"之前,作者用了很多年时间回避这件事——他先是尝试用各种框架、插件和工具的组合,去解决 FastAPI 如今覆盖的全部能力(数据校验、序列化、自动文档、高性能、依赖注入……)。
直到某一天,除了"从过去工具中取最好的想法、用此前甚至不存在的语言能力(Python 3.6+ 的 type hints)把它们以最佳方式组合起来"之外,已经别无选择。理解这条"从组合到自研"的演进路径,是理解 FastAPI 全部设计取舍的钥匙。
下面按官方文档的顺序,把这条路径上的每一个"站点"过一遍。
一、此前工具的谱系:FastAPI 借鉴了什么
Django:成熟全能框架的两面性
Django 是最流行、被广泛信赖的 Python 框架,曾被用来构建 Instagram 这类系统。但它与关系型数据库(MySQL、PostgreSQL)耦合较紧,想用 NoSQL 数据库(Couchbase、MongoDB、Cassandra 等)作为主存储引擎并不容易。
更重要的是定位差异:Django 生来是在后端渲染 HTML,而不是为现代前端(React、Vue.js、Angular)或 IoT 设备等外部系统提供 API。FastAPI 从中看到的启示更多是"反面教材"——一个 Web 框架不必把 HTML 渲染、用户管理等能力全部内置。
Django REST Framework:自动 API 文档的启蒙者
Django REST Framework(DRF)是在 Django 之上构建 Web API 的灵活工具包,被 Mozilla、Red Hat、Eventbrite 等公司使用。它是"自动 API 文档"最早的示范之一,也正是触发作者"寻找 FastAPI"的第一个想法。
值得记住的一条人物线索:DRF 由 Tom Christie 创建,而 Starlette 与 Uvicorn 同样出自他手——这两者正是 FastAPI 的地基。
FastAPI 借鉴点:提供自动生成 API 文档的 Web 用户界面。
Flask:微框架哲学的直接继承者
Flask 是"microframework",不带数据库集成,也不带 Django 默认内置的众多功能。这种简洁与灵活性恰恰允许你用 NoSQL 当主存储;同时它学习曲线平缓,常用于那些并不真正需要数据库、用户管理等开箱即用特性的应用。
文档明确指出:部件解耦 + 可精确扩展的微框架,是作者"想要保留的关键特性"。基于 Flask 的简洁,它很适合构建 API,于是下一步自然是寻找"Flask 版的 Django REST Framework"。
FastAPI 借鉴点:
- 做一个微框架,让所需工具与部件可以自由 mix and match;
- 拥有简单易用的路由系统。
Requests:客户端 API 风格反向塑造服务端 API
FastAPI 并不是 Requests 的替代品——两者作用域完全不同,在 FastAPI 应用内部使用 Requests 反而是常见操作。Requests 是调用 API(客户端)的库,FastAPI 是构建 API(服务端)的库,分处互补的两端。
Requests 的设计简单直观、默认值合理、开箱即用,同时强大且可定制,也因此成为有史以来下载量最高的 Python 包之一。看这两段代码的对称性:
response = requests.get("http://example.com/some/url")
@app.get("/some/url")
def read_url():
return {"message": "Hello World"}
requests.get(...) 与 @app.get(...) 的相似性并非巧合。在 FastAPI 源码中,这些 HTTP 方法确实是直接以装饰器形式暴露在应用与路由上的,例如 fastapi/routing.py 中 api_route、get、post、put、delete 等路径操作方法。
FastAPI 借鉴点:
- 简洁直观的 API;
- 直接用 HTTP 方法名(操作)声明端点,直白不绕弯;
- 有合理的默认值,又保留强大的定制能力。
Swagger / OpenAPI:拥抱开放标准而非私有 Schema
作者从 Django REST Framework 想拿走的核心能力是自动 API 文档。随后他发现业界已有用 JSON(或 YAML)描述 API 的标准 Swagger,且 Swagger 的 Web 用户界面早已存在——只要能生成 Swagger 文档,就能自动套用这套 UI。
后来 Swagger 被交给 Linux Foundation 并更名为 OpenAPI:因此聊 2.0 版本时习惯叫 "Swagger",3+ 版本则称 "OpenAPI"。
FastAPI 借鉴点:为 API 规范采用开放标准(而非自定义 schema),并集成基于标准的 UI 工具——Swagger UI 与 ReDoc。选择二者是因为足够流行与稳定;事实上针对 OpenAPI 还有数十种其它界面可直接与 FastAPI 搭配使用。
Flask REST frameworks:放弃的原因
市面上有多个 Flask REST 框架,但作者投入时间调研后发现:许多已经停止维护或被废弃,且存在大量未解决的关键 issue,因此无法胜任。
Marshmallow:用代码而非特设类定义 Schema
API 系统两个核心需求之一叫数据"serialization(序列化)":把 Python 对象(比如来自数据库的数据、datetime 对象)转换成能走网络的形式。另一个核心需求是数据校验:确认某字段确实是 int 而非任意字符串——这对外部传入数据尤其重要,没有校验系统就得手写所有检查。
Marshmallow 正是为这两点而生,作者此前大量使用过它。但它诞生于 Python type hints 出现之前,定义每个 schema 必须借助它提供的专属 utils 与 classes。
FastAPI 借鉴点:用代码定义 "schemas",让它自动提供数据类型与校验。
这也直接解释了为何 FastAPI 选择 Pydantic——见下文第三部分。
Webargs:请求数据的自动解析与校验
API 的另一个核心需求是从入站请求中 parsing(解析) 数据。Webargs 专门在 Flask 等多个框架之上提供这一点,底层用 Marshmallow 做校验,且出自同一批开发者。
FastAPI 借鉴点:对入站请求数据做自动校验。
APISpec:文档缺失的补课,但引入了"字符串内嵌语法"问题
Marshmallow 与 Webargs 以插件形式解决了校验、解析与序列化,但文档仍缺失,于是有了 APISpec。它同样是多框架(含 Starlette)的插件:做法是在每个处理路由的函数 docstring 里用 YAML 书写 schema 定义,再由它生成 OpenAPI schema。
问题也随之而来:YAML 是嵌在 Python 字符串里的"微语法",编辑器难以提供帮助;一旦改了参数或 Marshmallow schema 却忘记同步改 docstring,生成的 schema 就会过期。这是 FastAPI 明确要避免的陷阱——因此它坚持"单一事实来源":从同一份类型声明同时产出校验、序列化与文档。
FastAPI 借鉴点:支持 OpenAPI 这一 API 开放标准。
Flask-apispec:作者此前的"心头好"与它的上限
Flask-apispec 把 Webargs、Marshmallow、APISpec 串成一个 Flask 插件,用 Webargs/Marshmallow 的信息经由 APISpec 自动生成 OpenAPI schema,解决了"在 Python docstring 里手写 YAML"的问题。作者评价它"被严重低估",并指出 Flask + Flask-apispec + Marshmallow + Webargs 是他构建 FastAPI 前最喜欢的后端组合。
这一组合还催生了多个 Flask full-stack generators,而这些生成器后来正是 FastAPI 项目生成器(对应文档 docs/en/docs/project-generation.md)的前身。
FastAPI 借鉴点:从同一份定义序列化与校验的代码中,自动生成 OpenAPI schema——这正是 FastAPI + Pydantic 的核心机制。
NestJS(与 Angular):编辑器支持与依赖注入的参照系
NestJS 甚至不是 Python——它是受 Angular 启发的 JavaScript/TypeScript NodeJS 框架。它能做到与 Flask-apispec 类似的事情,并拥有受 Angular 2 启发的内置依赖注入系统,但要求预先注册 "injectables",带来一定的啰嗦与代码重复。
参数用 TypeScript 类型描述让编辑器支持相当好;可 TypeScript 类型在编译为 JavaScript 后不复存在,无法仅靠类型同时定义校验、序列化与文档,于是不得不在大量位置叠加装饰器,代码相当冗长;它对嵌套模型的处理也不佳——请求 JSON body 内部再有嵌套 JSON 对象时,难以被正确文档化与校验。
FastAPI 借鉴点:
- 用 Python 类型换取出色的编辑器支持;
- 拥有强大的依赖注入系统,并想办法把代码重复降到最低。
Sanic:基于 asyncio 的高性能先驱
Sanic 是最早一批基于 asyncio 的极速 Python 框架之一,形态上刻意接近 Flask。技术细节在于它使用 uvloop 替代 Python 默认的 asyncio loop——这正是它快的原因,也启发了 Uvicorn 与 Starlette。
FastAPI 借鉴点:寻找获得惊人性能的路径。这正是 FastAPI 选择基于 Starlette 的原因——按第三方 benchmark 测试,Starlette 是可用的最快框架。
Falcon:request/response 双参数设计带来的局限
Falcon 是另一个高性能 Python 框架,设计上追求极简,并作为 Hug 等框架的地基。它的函数接收两个参数——一个 "request"、一个 "response",从中"读"、"写"数据。这一设计决定了:无法用标准 Python type hints 把请求参数与 body 声明为函数参数,于是数据校验、序列化与文档只能在代码里手写,或另建一层框架(如 Hug)来实现。
FastAPI 借鉴点:获得优秀性能的方法;同时它与 Hug(Hug 基于 Falcon)共同启发了 FastAPI 在函数中声明
response参数——在 FastAPI 中该参数是可选,主要用于设置 headers、cookies 与替代状态码。
Molten:类型驱动思想的早期同路人
作者在构建 FastAPI 初期发现了 Molten,二者想法相当接近:基于 Python type hints、由类型派生校验与文档、带依赖注入系统。差异在于:
- Molten 不用 Pydantic 这类第三方校验库而是自带实现,导致数据类型定义不易复用;
- 配置更冗长,且基于 WSGI(而非 ASGI),无法享受 Uvicorn、Starlette、Sanic 提供的高性能;
- 依赖注入要求预注册,且按声明类型解析,无法为同一类型声明多个提供者;
- 路由集中在一处声明、调用别处定义的函数(而非紧贴端点的装饰器),更接近 Django 而不是 Flask/Starlette 的做法,人为拆散了本应紧耦合的代码。
FastAPI 借鉴点:用模型属性的 "default" 值表达数据类型的额外校验——这改善了编辑器支持,且当时 Pydantic 并不具备。该想法后来甚至反向推动了 Pydantic 更新,如今这部分能力已全部内置于 Pydantic。
Hug:type hints 声明参数的先行者
Hug 是最早用 Python type hints 声明 API 参数类型的框架之一,尽管它用的是自定义类型而非标准 Python 类型,仍是巨大进步;它也是最早为整个 API 生成 JSON 自定义 schema 的框架之一。不过它并不基于 OpenAPI / JSON Schema 这类标准,与 Swagger UI 等工具集成并不直接。它还具备罕见的特性:同一框架既能构建 API 也能构建 CLI。由于它基于 WSGI(同步 Python Web 框架的旧标准),无法处理 WebSocket 等场景,尽管性能同样出色。
人物注记:Hug 由 Timothy Crosley 创建,他同时也是
isort的作者。FastAPI 借鉴点:Hug 启发了 APIStar 的部分设计;它推动 FastAPI 用 Python type hints 声明参数、自动生成定义 API 的 schema,并在函数中声明
response参数以设置 headers 与 cookies。
APIStar(<= 0.5):FastAPI 的"精神前身"
在决定构建 FastAPI 前不久,作者发现了 APIStar server——它几乎具备他寻找的一切且设计出色:是较早用 Python type hints 声明参数与请求的框架实现之一(早于 NestJS 与 Molten),并且采用了 OpenAPI 标准;能基于同一套 type hints 做数据校验、序列化与 OpenAPI schema 生成。但 body schema 更接近 Marshmallow 风格,编辑器支持不算最好。
彼时 APIStar 的 benchmark 是最优的(仅被 Starlette 超越);最初没有自动文档 UI,但作者清楚可以接入 Swagger UI;它拥有依赖注入系统,但同样要求预注册组件;并且缺少 security 集成,作者始终无法在完整项目中替换掉 Flask-apispec 全栈方案。
随后项目焦点转移:它不再是 API Web 框架(作者需聚焦 Starlette),今天 APIStar 是校验 OpenAPI 规范的工具集而非 Web 框架。
人物注记:APIStar 同样出自 Tom Christie——Django REST Framework、Starlette(FastAPI 的底座)、Uvicorn(Starlette 与 FastAPI 的运行服务器)的同一作者。
FastAPI 借鉴点:让它存在。用同一套 Python 类型同时声明数据校验、序列化与文档、且自带出色编辑器支持——这个想法是 FastAPI 的灵魂。APIStar 停更后,Starlette 成为新的、更好的地基,这也是构建 FastAPI 的最终灵感。作者将 FastAPI 视为 APIStar 的 "spiritual successor",在吸收上述所有工具经验的基础上改进并扩展了特性、类型体系与其余部件。
二、FastAPI 脚下踩的三块基石
如果说上一部分是"曾经走过、最终舍弃的路",这一部分则是 FastAPI 最终"选择站在谁的肩膀上"。
Pydantic:数据校验、序列化与 JSON Schema
Pydantic 是基于 Python type hints 定义数据校验、序列化与文档(JSON Schema)的库,因此极其直观。它与 Marshmallow 相当,但 benchmark 中更快;且因同样建立在 type hints 之上,编辑器支持出色。
FastAPI 用它处理全部数据校验、数据序列化与基于 JSON Schema 的模型自动文档化,再把 JSON Schema 数据连同其它能力一起汇入 OpenAPI。仓库层面可以印证这一依赖:在 pyproject.toml 中 dependencies 显式声明了 pydantic>=2.9.0;FastAPI 的所有请求/响应模型解析、校验错误处理均围绕 Pydantic 模型体系展开(如 tests 目录中大量 test_validate_response*.py、test_response_model*.py 用例)。
Starlette:ASGI 微框架地基
Starlette 是轻量级 ASGI 框架/工具包,天生适合构建高性能 asyncio 服务,设计上易于扩展、组件模块化。文档列出它的能力清单:
- 相当出色的性能;
- WebSocket 支持;
- 进程内后台任务;
- 启动与关闭事件;
- 基于 HTTPX 的 TestClient;
- CORS、GZip、Static Files、流式响应;
- Session 与 Cookie 支持;
- 100% 测试覆盖率与 100% 类型注解代码库、依赖极少。
Starlette 提供全部基础 Web 微框架功能,但不提供自动数据校验、序列化或文档——这正是 FastAPI 叠加在其上的主要价值(全部基于 type hints + Pydantic),外加依赖注入、安全工具、OpenAPI schema 生成等。
技术细节:ASGI 由 Django core team 成员推动发展,虽尚未成为 Python 标准(PEP),但已被众多工具当作事实标准使用,大幅提升了互操作性——例如可将 Uvicorn 换成 Daphne、Hypercorn 等任意 ASGI server,或接入
python-socketio等 ASGI 兼容工具。FastAPI 用 Starlette 处理全部核心 Web 部件,并在其上叠加特性。代码层面可直接验证:在 fastapi/applications.py 第 42 行,
class FastAPI(Starlette)——FastAPI 应用类直接继承自 Starlette。这意味着"凡是 Starlette 能做的,FastAPI 都能直接做",它本质上就是"加了料的 Starlette"。
Uvicorn:闪电般的 ASGI 服务器
Uvicorn 是基于 uvloop 与 httptools 构建的高速 ASGI server。它不是框架——例如不提供按路径路由的能力,那由 Starlette(或 FastAPI)这类框架在上层提供。Uvicorn 是运行 Starlette 与 FastAPI 应用的推荐服务器,也内置在仓库的依赖与 CLI 中(pyproject.toml 的 uvicorn[standard] 依赖,以及 fastapi/cli.py、fastapi/__main__.py 提供的命令行入口)。
FastAPI 将 Uvicorn 作为运行应用的主 Web server,并可通过
--workers命令行参数获得异步多进程能力。更多细节见 Deployment 部署章节。
三、性能与基准:三者关系如何理解
Uvicorn、Starlette 与 FastAPI 三者的层级关系常被混淆:Uvicorn 是 ASGI 服务器、Starlette 是 ASGI 框架/工具包、FastAPI 是在 Starlette 之上叠加数据校验与文档能力的应用框架。要理解、比较并看清三者的差异,官方文档指向了专门的 Benchmarks 基准章节(英文原版见 docs/en/docs/benchmarks.md)。
结合本文第一部分可以看到清晰的传承链:Sanic 用 uvloop 证明"Python 也可以极快"→ 启发 Uvicorn 与 Starlette → 作者在考察了 Django REST Framework、Flask-apispec、APIStar 等一整套方案后,最终选择"基于 Starlette 加 Pydantic 的 FastAPI"——用星标式的一句话概括,即:从过去的工具里取回正确的想法,用 type hints 这一新语言能力把它们整合成单一、可自动化的栈。
结语:一份可复用的"框架选型检查清单"
回看整个谱系,FastAPI 对每个前身工具的关注点其实高度收敛,可以归纳成一张评估"Web API 框架"的通用清单,这也是阅读 docs/hi/docs/alternatives.md 最有价值的产出:
- 是否基于(或兼容)开放标准:Swagger/OpenAPI 取代自定义 schema 是文档与工具生态打通的前提;
- 声明是否只有单一事实来源:docstring 内嵌 YAML(APISpec 路线)必然面临"改代码忘改文档"的过期问题;
- 类型是否贯穿编译/运行期:TypeScript 类型编译后消失,导致 NestJS 需大量装饰器补偿;Python type hints 在运行期保留,得以同时驱动校验、序列化与文档;
- 运行时是否面向未来:WSGI 系(Molten、Hug)难以覆盖 WebSocket 等高阶能力,ASGI 系(Starlette)才有完整异步生态;
- 依赖注入是否零预注册:预注册组件(NestJS、Molten、APIStar)带来代码重复,FastAPI 用"类型即契约"的声明式方案规避;
- 性能是否经第三方验证:从 Sanic 的 uvloop 到 Starlette,性能是框架选型中可被 bench mark 实证的硬指标;
- 嵌套模型能否被正确文档化与校验:这是 NestJS 等框架的短板,也是 FastAPI 依托 Pydantic 递归模型能力的优势所在。
最终,FastAPI 选择站在 Pydantic(类型驱动的校验/序列化/JSON Schema)+ Starlette(ASGI 微框架地基)+ Uvicorn(ASGI 服务器) 之上——正如仓库源码所证实的那样,FastAPI 类直接继承 Starlette(fastapi/applications.py),而 starlette 与 pydantic 被列为最核心的运行时依赖(pyproject.toml)。理解了这条从 Django 一路延伸而来的"灵感与替代"脉络,你也就理解了 FastAPI 为什么长成今天的样子。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00