引言
FastAPI 是 Python 生态中性能最高的 Web 框架之一,在 TechEmpower 基准测试中接近 Node.js 和 Go 框架的水平。它的核心卖点不仅是快——类型提示驱动的自动数据验证、自动 OpenAPI 文档生成、优雅的依赖注入系统,让 API 开发效率大幅提升。
FastAPI 的 GitHub Star 数已超过 8 万,成为 Python Web 开发的首选框架。今天我们从源码层面,拆解它的核心设计。
项目背景
FastAPI 由 Sebastián Ramírez 创建,构建在两个核心依赖之上:
- Starlette:ASGI Web 框架,提供路由、中间件、WebSocket 等基础能力
- Pydantic:数据验证库,基于 Python 类型提示实现高性能的数据解析和校验
FastAPI 本身的代码量并不大(核心约 8000 行 Python),它的价值在于将 Starlette 的高性能和 Pydantic 的类型安全巧妙地粘合在一起,并在此基础上构建了依赖注入和自动文档系统。
核心源码解析
1. ASGI 基础与 Starlette
FastAPI 继承自 Starlette,本质上是一个 ASGI 应用:
# FastAPI 的类继承关系
class FastAPI(Starlette):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.router = APIRouter()
# 自动生成 OpenAPI 文档路由
if self.openapi_url:
self.add_route(self.openapi_url, self._openapi_route)
self.add_route(self.docs_url, self._swagger_ui_route)
# ASGI 应用的核心接口
# 每个请求都会调用这个方法
async def __call__(self, scope, receive, send):
# scope: 请求元信息(路径、方法、头部等)
# receive: 接收请求体的异步函数
# send: 发送响应的异步函数
await self.middleware_stack(scope, receive, send)
ASGI(Asynchronous Server Gateway Interface)是 Python 异步 Web 应用的标准接口,类似于 WSGI 的异步版本。FastAPI 通过 Uvicorn(基于 uvloop)运行,获得接近 C 语言的事件循环性能。
2. Pydantic 数据验证
FastAPI 利用 Python 类型提示和 Pydantic 实现自动数据验证:
from pydantic import BaseModel
from fastapi import FastAPI
class UserCreate(BaseModel):
name: str
email: str
age: int # Pydantic 自动验证类型
app = FastAPI()
@app.post("/users")
async def create_user(user: UserCreate):
# user 已经过 Pydantic 验证,类型安全
return {"id": 1, "name": user.name}
# FastAPI 内部的参数解析逻辑(简化)
async def solve_dependencies(*, request: Request, dependant: Dependant):
values = {}
errors = []
# 解析请求体
if dependant.body_params:
body = await request.json()
# 使用 Pydantic 模型验证
try:
validated = dependant.model.model_validate(body)
values.update(validated.model_dump())
except ValidationError as e:
errors.extend(e.errors())
# 解析路径参数
for param in dependant.path_params:
raw_value = request.path_params.get(param.name)
# 自动类型转换
values[param.name] = param.type_(raw_value)
return values, errors
Pydantic v2 底层使用 Rust 编写的 pydantic-core,验证速度比 v1 快 5-50 倍。
3. 依赖注入系统
FastAPI 的依赖注入是其最强大的特性之一:
from fastapi import Depends
# 定义依赖
async def get_db():
db = Database()
try:
yield db # yield 之前的代码在请求前执行
finally:
await db.close() # yield 之后的代码在请求后执行
async def get_current_user(db = Depends(get_db), token: str = Header()):
user = await db.get_user_by_token(token)
if not user:
raise HTTPException(status_code=401)
return user
@app.get("/profile")
async def get_profile(user = Depends(get_current_user)):
return user
# 依赖解析器的核心逻辑(简化)
class DependencySolver:
async def solve(self, dependant: Dependant, request: Request):
# 递归解析依赖树
sub_values = {}
for sub_dep in dependant.dependencies:
# 检查缓存(同一请求中相同依赖只执行一次)
if sub_dep.cache_key in self._cache:
sub_values[sub_dep.name] = self._cache[sub_dep.cache_key]
continue
# 递归解析子依赖
solved = await self.solve(sub_dep.dependant, request)
# 调用依赖函数
if is_gen_callable(sub_dep.call):
# generator 依赖(带 yield 的)
cm = contextmanager_in_threadpool(sub_dep.call(**solved))
value = await cm.__aenter__()
else:
value = await sub_dep.call(**solved)
sub_values[sub_dep.name] = value
self._cache[sub_dep.cache_key] = value
return sub_values
依赖注入系统支持嵌套依赖、依赖缓存、generator 依赖(用于资源管理),且完全基于类型提示,无需装饰器或配置文件。
4. 自动 OpenAPI 文档生成
FastAPI 通过分析路由函数的类型提示,自动生成 OpenAPI 规范文档:
def get_openapi_path(route: APIRoute) -> dict:
path_item = {}
for method in route.methods:
operation = {
"summary": route.summary or route.name,
"operationId": route.operation_id,
"parameters": [],
"responses": {},
}
# 从函数签名提取参数信息
for param in route.dependant.path_params:
operation["parameters"].append({
"name": param.name,
"in": "path",
"required": True,
"schema": get_schema_from_type(param.type_),
})
# 从 Pydantic 模型生成请求体 Schema
if route.dependant.body_params:
model = route.dependant.model
operation["requestBody"] = {
"content": {"application/json": {
"schema": model.model_json_schema()
}}
}
path_item[method.lower()] = operation
return path_item
这意味着你写完 API 代码,文档就自动生成了——Swagger UI 和 ReDoc 界面开箱即用。
关键设计模式
1. 类型驱动开发:Python 类型提示不仅用于 IDE 补全,还驱动数据验证、序列化和文档生成。 2. 依赖注入:通过 Depends() 实现声明式的依赖管理,支持嵌套、缓存和生命周期管理。 3. 分层架构:Starlette 处理 HTTP 协议,Pydantic 处理数据验证,FastAPI 负责粘合和增强。 4. 约定优于配置:函数参数名自动映射到路径参数、查询参数或请求体,减少样板代码。总结
FastAPI 的成功在于它站在了 Starlette 和 Pydantic 两个优秀项目的肩膀上,并通过依赖注入和自动文档生成创造了巨大的开发体验提升。它证明了 Python 在 Web 开发领域不仅可以"够用",还可以"很快"。如果你在设计 API 框架,FastAPI 的类型驱动设计思路非常值得借鉴。