FastAPI 框架的设计源流:灵感来源、同类框架横向对比与技术取舍全景解析
导读:本文围绕官方文档 Alternativas, Inspiración y Comparaciones(《备选方案、灵感来源与对比》)展开,系统梳理 FastAPI 诞生的技术背景、所借鉴的十余个历史框架与工具(Django、Flask、Requests、APIStar、Molten 等),深入剖析 FastAPI 直接采用并深依赖的 Pydantic、Starlette、Uvicorn 三者分工,并结合当前仓库源码(如 applications.py、pyproject.toml)给出证据支撑。读完你将理解 FastAPI 的"为什么":它的类型驱动设计、自动文档、依赖注入、高性能路线分别继承自谁、舍弃了什么、又在哪里做出了关键性创新。
为什么需要了解 FastAPI 的"前世今生"
了解一个框架不能只看它的 API,还要看它解决的问题从何而来。官方文档用整章篇幅回顾了 FastAPI 的创作动机与灵感来源,核心观点可以概括为一句话:FastAPI 并不是凭空设计出来的全新事物,而是作者在多年尝试 Flask、Flask-apispec、Marshmallow、Webargs 等组合方案后,意识到"缺少一个把所有能力统一起来的框架",最终基于 Python 类型注解(type annotations)这一当时还相当新的语言特性,将前人最好的想法重新组合的产物。
在文档中,作者坦诚地写道:
FastAPI 不存在,如果没有其他人的工作。许多工具在此之前被创建,它们帮助启发了 FastAPI 的诞生。
具体而言,创作动因包括:
- 作者曾多年回避"再造一个框架",而是试图用大量不同框架、插件与工具组合来覆盖最终 FastAPI 提供的能力;
- 直到某一点,他意识到唯一的出路是创造一个新框架,把此前工具的最佳思想合并起来;
- 而这一设想之所以到那时才可行,是因为 Python 3.6+ 提供了类型注解特性,让"一份代码同时声明类型、校验、序列化与文档"成为可能。
值得一提的是,原文档写作时代面向 Python 3.6+,而当前仓库 pyproject.toml 中 requires-python = ">=3.10",且 docs_src 内的教程示例统一以 py310 命名,说明这一"用类型注解驱动一切"的设计理念随语言演进进一步强化——本仓库已是面向 Python 3.10+ 时代整理的文档与源码快照。
灵感来源:推动 FastAPI 走向成形的历史框架
原文将激励来源归纳为一条清晰的"谱系链",下面按原文脉络逐个梳理,并提炼每项工具给 FastAPI 带来的具体启示。
Django:最流行的"全家桶"及其边界
Django 是 Python 生态中最流行、最被广泛信赖的框架,作者指出它被用来构建 Instagram 这类大型系统。但它有两个结构性特点限制了它在作者当时场景下的适用性:
- 与关系型数据库(MySQL、PostgreSQL 等)耦合较深,如果想把 NoSQL(Couchbase、MongoDB、Cassandra 等)作为主存储引擎,会相当不顺手;
- 它最初的设计目标是在服务端生成 HTML,而不是面向现代前端(React、Vue.js、Angular)或 IoT 设备提供 API 数据。
这两点正是"API 优先"框架要解决的核心场景。原文据此给出的启示并不在于模仿 Django,而在于明确了一个反面边界:FastAPI 不必把服务器渲染、ORM 全家桶都内置进来。
Django REST Framework:自动 API 文档的启蒙者
Django REST Framework(DRF)是建立在 Django 之上的 Web API 工具包,被 Mozilla、Red Hat、Eventbrite 等公司使用。它对 FastAPI 最重要的意义,是最早让作者意识到"API 自动文档"可以成为一个框架的内建能力——这也是 FastAPI 追求的目标之一。
它是 API 自动文档的首批示例之一,而这一点正是最初启发作者"寻找" FastAPI 的想法之一。
原文特别注明了一个关键人物关系:DRF 由 Tom Christie 创建,他同时也是 Starlette 与 Uvicorn 的创造者,而这两者正是 FastAPI 的地基。 这条人物线贯穿了 Django REST Framework → APIStar → Starlette → Uvicorn → FastAPI 的完整谱系。
Flask:微框架哲学与"只取所需"的自由
Flask 是"微框架"(microframework),默认不捆绑数据库集成与 Django 自带的大量功能。这份简单与灵活使它能够支持 NoSQL 等非默认存储方案,学习曲线相对友好。作者尤其看重它的两点特质并希望 FastAPI 保留:
- 微框架的"可拼装"哲学:需要什么就加什么,各部分相互解耦;
- 简单直观的路由系统。
文档写道,基于 Flask 的简洁性,它看起来非常适合用来构建 API,于是作者的下一步是寻找"Flask 版的 Django REST Framework"——这直接引出了下文的一批 Flask REST 生态工具。需要指出,FastAPI 团队也延续了这套哲学:核心依赖极少(见 pyproject.toml,仅 starlette、pydantic、typing-extensions、typing-inspection、annotated-doc 五项),而表单、模板、测试客户端、邮箱校验等能力全部通过 standard 附加依赖(optional-dependencies)按需安装。
Requests:极简 API 设计范本(客户端视角)
Requests 是 Python 中与 API 打交道的 HTTP 客户端库,而 FastAPI 是构建 API 的服务端框架,二者本不构成"替代"关系,甚至常常搭配使用——在 FastAPI 应用内部用 Requests 去调用别的服务非常常见。但 FastAPI 从 Requests 身上学到了大量 API 设计语言:
- API 要简单直观;
- 直接用 HTTP 方法名(operation)作为函数入口,例如
GET就对应requests.get; - 提供合理默认值,同时保留强大定制能力。
原文用一段极富说服力的对照代码展示这份"对称性"——客户端发起 GET 请求:
response = requests.get("http://example.com/some/url")
与之对应的 FastAPI path operation(服务端接收该请求)写法是:
@app.get("/some/url")
def read_url():
return {"message": "Hello World"}
requests.get(...) 与 @app.get(...) 的相似并非巧合,而是有意的设计传承。在仓库中,这套以 HTTP 动词命名的方法实现在 routing.py 的 APIRouter 类中:get、post、put、delete、patch、options、head 等装饰器方法一应俱全(约 routing.py 起依次定义),而 FastAPI 应用对象本身复用同一套 APIRouter。此外 Requests 官网自称"有史以来被下载最多的 Python 包之一"——原文引用这一说法,意在说明"简单直观"的 API 设计能带来多广的接受度。
Swagger / OpenAPI:从私有 schema 走向开放标准
作者从 DRF 获得的最大愿望是 API 自动文档,随后发现业界已有描述 API 的开放标准——Swagger(以 JSON 或其超集 YAML 描述 API),并且已经有基于 Swagger 的 Web UI。只要能输出 Swagger 规格,就能直接套用现成的交互式文档界面。
后来 Swagger 被移交给 Linux Foundation 并更名 OpenAPI:一般 2.0 时代称 "Swagger",3.x 起称 "OpenAPI"。FastAPI 由此得到两个明确启示:
- 采用开放的 API 标准,而不是自造私有 schema;
- 对接基于标准的文档 UI 工具:Swagger UI 与 ReDoc(文档提到二者因流行且稳定被选中,而 OpenAPI 生态中还有大量同类 UI 可选)。
这一设计在当前仓库中有非常直接的落地证据:FastAPI 启动时会自动挂载 /openapi.json、/docs(Swagger UI)与 /redoc(ReDoc)三条路由,见 applications.py,且三个 URL 均可通过构造参数 openapi_url、docs_url、redoc_url 定制(例如 FastAPI(docs_url="/documentation", redoc_url=None),见 applications.py 的文档字符串示例)。生成的 OpenAPI schema 默认版本为 3.1.0,见 openapi/utils.py。
Flask REST 生态的困境:Flask-apispec 组合的成败
作者调研了多个 Flask REST 框架,发现许多已停止维护或不适合生产;而随后登场的一组"黄金组合"则构成了他构建 FastAPI 之前最钟爱的后端技术栈:Flask + Flask-apispec + Marshmallow + Webargs。逐一看它们各解决什么问题:
| 工具 | 解决的问题 | FastAPI 的继承方式 |
|---|---|---|
| Marshmallow | 数据序列化(把 datetime、ORM 对象等转成可传输的 JSON)与数据校验(确保字段是 int 而不是任意字符串等) |
用 Python 代码定义"schemas",自动获得类型与校验。但它诞生于 Python 类型注解出现之前,需借助专用类与工具定义 schema |
| Webargs | 解析入站请求数据(由 Marshmallow 提供底层校验),由同一批作者开发 | 对入站请求数据的自动校验 |
| APISpec | 在函数 docstring 里用 YAML 微语法写 schema 定义,据此生成 OpenAPI | 支持开放标准 OpenAPI |
| Flask-apispec | 把上述三者串起来:用 Webargs/Marshmallow 信息自动生成 OpenAPI,免去手写 YAML | 从"定义序列化与校验的同一份代码"自动生成 OpenAPI schema |
这套组合解决了"手写 YAML"的问题,却仍留下结构性痛点——docstring 里的 YAML 是字符串中的微语法:编辑器几乎无法提供帮助;一旦改了 Marshmallow 参数或 schema 而忘记同步 YAML,生成出的文档就会失真过期。Flask-apispec 本身被作者评价为"非常被低估的好工具",其文档过于简洁抽象可能是它不够流行的原因。
这些基于 Flask 的 full-stack 项目生成器后来直接成为 FastAPI 项目生成器(Project Generators)的基础,见 project-generation.md。
NestJS 与 Angular:TypeScript 世界的镜鉴
NestJS 是受 Angular 启发的 Node.js/TypeScript 框架,并非 Python 工具,但它实现了与 Flask-apispec 类似的目标。作者从 NestJS(及其背后的 Angular 依赖注入)观察到了三个反面教材式的问题:
- DI 系统需要预先注册"可注入项",带来额外冗余与重复代码;
- TypeScript 的类型信息在编译成 JavaScript 后不保留,因此无法像 Python 运行时类型那样"一份类型同时用于校验、序列化与文档",只能靠到处写装饰器补救,导致冗长;
- 嵌套模型处理不佳——当请求 JSON body 的字段本身是嵌套 JSON 对象时,难以被正确文档化与校验。
与之相对的正面收获则是:使用带类型的语言/注解能带来优秀的编辑器支持,以及"强大的依赖注入 + 最小化代码重复"的追求。有趣的是,FastAPI 之所以能在 Python 上达成"运行时保留类型"的效果,正是因为 Python 的类型注解会在运行时真实可查,再由 Pydantic 把这些注解转化为校验与 JSON Schema 能力。
Sanic:asyncio 高并发路线的最早探路者
Sanic 是 Python 最早基于 asyncio 的超高速框架之一,API 形态刻意贴近 Flask。文档的"技术细节"注明:它使用 uvloop 替代 Python 默认的 asyncio event loop,这是它速度的来源,也直接启发了 Uvicorn 与 Starlette(作者称二者在公开基准测试中已快于 Sanic)。
Sanic 给 FastAPI 的启示是追求惊艳的性能;而 FastAPI 之所以选择建立在 Starlette 之上,正是因为作者认为(依据第三方基准测试)它是当时可用的最快框架。
Falcon:request/response 对象范式与 Hug
Falcon 是另一个 Python 高性能框架,设计上走极简路线,作为 Hug 等上层框架的底座。它的核心风格是处理函数接收两个参数 request 与 response,然后从 request "读"、向 response "写"。这种设计的代价是:无法用标准 Python 类型注解把请求参数和 body 声明为函数参数,于是校验、序列化、文档只能手写或由上层框架(如 Hug)补齐。
FastAPI 从 Falcon + Hug 中收获的灵感颇具戏剧性——采纳"在函数中声明一个 response 参数"这一想法,但在 FastAPI 里它被做成可选参数,主要用于设置响应 headers、cookies 或替代性状态码,而不是强制性的读写对象。仓库中关于 response 参数的这一可选用法,可对照 response 相关教程与 Response 注入机制查看(如 docs_src/response_change_status_code 与 docs_src/response_headers)。
Molten:理念最接近的"同行"
Molten 是作者在 FastAPI 早期就发现的框架,两者理念惊人相似:
- 都基于 Python 类型注解;
- 都从这些类型推导校验与文档;
- 都内置依赖注入(DI)。
但作者梳理出 Molten 的几处差异与局限:
- 它不用 Pydantic 这类第三方校验/序列化/文档包,而是自带一套类型系统,导致数据类型定义不易复用;
- 配置相对冗长,且基于 WSGI 而非 ASGI,无法享受 Uvicorn、Starlette、Sanic 所代表的高性能异步路线;
- DI 需要预先注册依赖,且按声明类型解析依赖,同一个类型无法注册多个"组件";
- 路由集中在一处声明,再引用别处定义的函数(更接近 Django 而非 Flask/Starlette 的装饰器紧贴处理函数风格),把相对内聚的代码拆散了。
Molten 反过来给 FastAPI(乃至 Pydantic)贡献了一个具体技巧:用模型属性的"默认值"(default)声明额外校验,这能显著改善编辑器体验,而当时的 Pydantic 尚不支持这种写法——这一思想最终推动了 Pydantic 相应能力的更新。Pydantic 生态当前的校验声明方式(Field 上的默认值约束、校验器等)正是这一历史对话的产物。
Hug:API + CLI 二合一的天才构想
Hug 是首批用 Python 类型注解声明 API 参数类型的框架之一,作者称之为"伟大突破"。它同时是首批用 JSON 声明并自动生成(私有)API schema 的框架。它的局限在于:schema 并非基于 OpenAPI/JSON Schema 开放标准,因此难以直接对接 Swagger UI 等生态工具。
Hug 还有一个少见的特色——用同一套代码既能构建 API 也能构建 CLI。由于基于同步 WSGI 标准,它无法处理 WebSocket 等异步能力(即便如此性能仍很高)。值得一提的花絮:Hug 由 Timothy Crosley 创建,他同时也是 isort(Python import 自动排序工具)的作者。
Hug 对 FastAPI 的启发清单在原文中非常明确:
- 用 Python 类型注解声明参数;
- 自动生成描述 API 的 schema;
- 支持在函数中声明
response参数,用于设置 headers 与 cookies。
APIStar(<= 0.5):FastAPI 的"精神前任"
APIStar 是压垮作者"再造轮子"心理防线的最后一根稻草。在决定构建 FastAPI 之前,作者发现 APIStar server 几乎具备他想要的一切:
- 最早用 Python 类型注解声明参数与请求的框架实现之一(早于 NestJS 与 Molten,作者大约同时期发现它与 Hug);
- 基于 OpenAPI 开放标准;
- 用同一批类型注解自动完成数据校验、序列化与 OpenAPI schema 生成;
- 当时基准测试成绩最佳(仅次于 Starlette);
- 内置依赖注入系统(虽然仍需预先注册组件)。
APIStar 的 body schema 定义并非标准 Python 类型(更接近 Marshmallow 风格),编辑器支持不够好,且当时缺少安全集成,使作者无法在完整项目中替换掉基于 Flask-apispec 的 full-stack 方案——他甚至计划为它提交 PR 补上安全能力。但随后项目方向剧变:其创建者转向专注 Starlette,APIStar 不再作为 Web 框架存在,如今只是校验 OpenAPI 规范的工具集,不再是服务器框架。
原文的"注释"再次点明人物线索:APIStar 同样出自 Tom Christie 之手——他同时创造了 Django REST Framework、Starlette(FastAPI 的地基)与 Uvicorn(Starlette 与 FastAPI 实际使用的服务器)。
正是 APIStar 的谢幕促成了 FastAPI 的诞生:APIStar 消失后,Starlette 成为更好、更新的地基,作者由此获得最终灵感,并明确表态:
我认为 FastAPI 是 APIStar 的"精神继任者"(spiritual successor),在其基础上改进并扩展了功能、类型系统与其他部分,同时吸收了所有这些早期工具的经验教训。
FastAPI 直接采用并深度依赖的三大组件
如果说上一节讲的是"灵感来源",这一节则是"直接地基"——FastAPI 不是从零实现一切,而是明确站在三个成熟组件的肩膀上,只负责把它们的缝隙补上。原文分别阐述了三者与 FastAPI 的分工。
Pydantic:数据校验、序列化与 JSON Schema
Pydantic 是一个基于 Python 类型注解定义数据校验、序列化与文档(JSON Schema)的包。文档认为它与 Marshmallow 定位可比,但基于同一套 Python 类型注解使其编辑器支持远胜,且(文档称)在基准测试中更快。
FastAPI 用它来做:处理全部数据校验、数据序列化与基于 JSON Schema 的模型自动文档;FastAPI 再把生成的 JSON Schema 汇入 OpenAPI,完成其余所有工作。
当前仓库对这份依赖给出了精确版本证据:pyproject.toml 声明 "pydantic>=2.9.0",且仓库包含 Pydantic v1 兼容教程(docs_src/pydantic_v1_in_v2)与大量 v2 兼容测试(如 tests/test_schema_compat_pydantic_v2.py),印证 Pydantic 在 FastAPI 中扮演的正是"类型 → 校验 → 文档"转换中枢。
Starlette:全部 Web 基础设施
Starlette 是轻量级 ASGI framework/toolkit,专为构建高性能 asyncio 服务而生。文档罗列了它自带的能力清单:
- 惊人的性能;
- WebSocket 支持;
- 进程内后台任务;
- 启动/关闭事件(lifespan);
- 基于 HTTPX 的测试客户端;
- CORS、GZip、静态文件、流式响应;
- 会话与 Cookie 支持;
- 100% 测试覆盖率;
- 100% 类型注解的代码库;
- 极少的强制依赖。
Starlette 提供了微框架应有的全部 Web 底层能力,但不提供自动数据校验、序列化或文档——这正是 FastAPI 在其上叠加的核心增量:类型驱动的校验/序列化、依赖注入系统、安全工具(security utils)、OpenAPI schema 生成等。
这一"继承关系"在当前仓库中是字面意义的代码事实:查看 applications.py 可以看到:
class FastAPI(Starlette):
也就是说 FastAPI 类直接继承自 Starlette 的 Starlette 类——原文"你能用 Starlette 做的任何事都能直接在 FastAPI 上做,因为它本质上是被增强的 Starlette"这一论断,可由源码逐字验证。
文档中的"技术细节"还解释了 ASGI 标准的当时状态:ASGI 是 Django 核心团队成员正在推动的新标准,当时还不是 Python 正式标准(PEP),但已被大量工具当作事实标准使用。其互操作性红利在于:可以随时把 Uvicorn 换成其他 ASGI 服务器(如 Daphne 或 Hypercorn),或接入 python-socketio 等 ASGI 兼容工具。
Uvicorn:ASGI 服务器与 --workers
Uvicorn 是基于 uvloop 与 httptools 构建的极速 ASGI 服务器。它不是 Web 框架——例如它不提供路径路由能力,那是 Starlette/FastAPI 这类框架在其上层提供的。
FastAPI 将它作为:运行 FastAPI 应用的主 Web 服务器;也可用命令行参数
--workers启动多进程异步服务器。
更多部署细节见官方 Deployment 文档。这也再次印证了 FastAPI 生态的分层哲学:服务器(Uvicorn)、Web 工具层(Starlette)、应用框架(FastAPI)、数据层(Pydantic)各司其职,均可独立替换。
性能主张应当如何理解
文档在结尾明确提醒:要理解 Uvicorn、Starlette 与 FastAPI 三者之间的差异,应去阅读 Benchmarks(基准测试)章节,仓库对应基准脚本可见 tests/benchmarks。
关于性能,文档给出的判断带有明确的作者视角与时点背景:作者认为 Starlette 是当时公开基准测试中最快的 Python 框架,其上方只有 Uvicorn——而 Uvicorn 本质是服务器而非框架;Sanic 的 uvloop 路线启发了 Uvicorn 与 Starlette,而后者在开放基准中已超越 Sanic。需要提醒的是:基准测试结果高度依赖场景、版本与硬件,这类"最快"表述属于文档作者基于彼时第三方基准的个人判断,不应被当作无条件成立的绝对事实。当前仓库自身也并未在 pyproject.toml 或其他配置中声明任何官方性能数字。
谱系图式的总结:一条可复用的技术判断框架
把全文线索收束起来,FastAPI 的设计取舍可以归纳为四条贯穿性的判断标准,任何想评估新框架的开发者都可以照此提问:
- 类型是否能"一份多用"? 是否能用一份 Python 类型注解同时驱动参数解析、数据校验、序列化与 OpenAPI 文档,避免 Marshmallow/YAML docstring 时代的"多处定义、易失同步"问题?(对照 Marshmallow、APISpec、NestJS 的反面经验)
- 是否站在开放标准上? 是否采用 OpenAPI/JSON Schema,从而直接接入 Swagger UI、ReDoc 等现成生态?(对照 Hug 私有 schema 的教训)
- 性能路线是否现代化? 是否基于 ASGI 而非 WSGI,能否利用 Uvicorn/Starlette 一系的异步高性能?(对照 Molten、Falcon 的 WSGI 局限)
- 是否追求微框架式的可拼装与低重复? 核心依赖精简、装饰器紧贴处理函数、DI 无需预注册、冗余降到最低?(对照 Django 的厚重、NestJS 的冗长与 APIStar/Molten 的预注册 DI)
而 FastAPI 之所以能被作者称为 APIStar 的"精神继任者",正在于它把上述所有正面答案集中在同一个类型系统之上,再以"站在 Starlette 之上"的方式继承了完整的 Web 能力。想进一步了解 FastAPI 在创作之后的设计演化与未来设想,可以继续阅读配套文档 history-design-future.md;想回顾 FastAPI 相对这些工具的全部能力亮点,可阅读 features.md。
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 StartedRust0626
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00