FastAPI 是什么
FastAPI 是当前 Python 社区最受欢迎的 Web 框架之一,它用一个朴素的想法解决了传统框架的痛点:把 Python 的类型提示当作接口契约,让校验、序列化、文档自动生成。你写函数签名时标注参数类型,FastAPI 就自动完成请求解析、数据校验、错误返回,甚至生成一份可点击试用的 OpenAPI 文档。
它基于两个成熟组件:Starlette 提供 ASGI 异步能力与路由,Pydantic 提供数据模型与校验。因此它天生支持异步并发,性能接近 Node.js 与 Go 的同类方案,同时保持了「纯 Python、可读性好」的开发体验。
选框架看三件事:开发效率、运行性能、生态成熟度。FastAPI 在这三件事上都很能打——类型提示即文档,异步开箱即用,社区插件覆盖了认证、ORM、任务队列等常见需求。
- 类型提示函数签名里的类型标注就是请求/响应契约,自动完成校验与序列化。
- Pydantic声明式数据模型,复杂嵌套校验只需一个类。
- 依赖注入用 Depends 组织数据库连接、鉴权、会话等横切逻辑。
- 自动文档/docs 提供可交互的 Swagger UI,接口调试零成本。
第一个接口:Hello World
先建好虚拟环境(方法见同频道的《Python 开发环境搭建与虚拟环境管理实战》),安装 FastAPI 与 Uvicorn,然后写一个最小应用:
pip install "fastapi" "uvicorn[standard]"
# main.py
from fastapi import FastAPI
app = FastAPI(title="我的第一个 API")
@app.get("/")
def read_root():
return {"message": "Hello, JijiyunCode"}
@app.get("/ping")
def ping():
return {"status": "ok"}
启动并访问:
uvicorn main:app --reload --port 8000
# 浏览器打开 http://127.0.0.1:8000/docs 查看自动生成的交互文档
# 打开 http://127.0.0.1:8000/openapi.json 查看 OpenAPI 规范
值得注意的细节:--reload 让代码改动即时生效,只用于开发;路由函数返回普通字典,FastAPI 自动序列化为 JSON——你不需要手动 json.dumps,也不用声明响应模型,类型标注已经替你说清楚了。
路径、查询参数与请求体
真实接口需要从三个位置拿数据:URL 路径、查询字符串、请求体。FastAPI 用类型标注区分它们——函数签名即参数来源:
from fastapi import FastAPI, Query, Path
app = FastAPI()
@app.get("/users/{user_id}")
def get_user(
user_id: int = Path(..., description="用户 ID"),
verbose: bool = Query(False, description="是否返回详情"),
):
return {"id": user_id, "verbose": verbose}
@app.post("/users")
def create_user(payload: dict):
# 请求体为 JSON,直接可用
return {"received": payload}
| 参数来源 | 写法 | 典型场景 |
|---|---|---|
| 路径参数 | user_id: int | 资源标识,如 /users/42 |
| 查询参数 | q: str | None = None | 过滤、分页、搜索 |
| 请求体 | payload: Item | 创建/更新资源 |
| 请求头 | x_token: str = Header(...) | 认证信息、自定义头 |
注意路径参数要声明在路径里({user_id}),查询参数直接写进签名——FastAPI 会按名字自动匹配。给参数加默认值表示可选,用 ... 表示必填,语义一目了然。
Pydantic 数据校验
把 payload: dict 换成 Pydantic 模型后,校验能力立刻升级:字段缺失、类型错误、非法枚举都会自动返回带详细信息的 422 错误,无需手写任何校验代码。
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(..., min_length=1, max_length=50)
price: float = Field(..., gt=0)
tags: list[str] = Field(default_factory=list)
@app.post("/items")
def create_item(item: Item):
# item 已通过校验,字段类型确定,IDE 有完整提示
return {"id": 1, **item.model_dump()}
常用技巧:
- 嵌套模型:模型字段可以是另一个模型,级联校验自动完成。
- 响应模型:
@app.post(..., response_model=ItemOut)控制返回字段与过滤敏感信息。 - 字段约束:
gt/ge/lt/le、min_length/max_length、pattern覆盖常见规则。 - 可选与默认:
field: int | None = None声明可空字段。
校验失败时的响应结构也固定(422 + errors 数组),前端与网关可以统一处理,这是把校验交给框架的最大红利。
依赖注入与数据库
依赖注入(Depends)解决「每个接口都要拿同一个东西」的重复问题——数据库会话、当前用户、配置对象,声明一次,处处复用,还支持嵌套与缓存。
from fastapi import Depends, FastAPI
app = FastAPI()
def get_db():
db = create_connection() # 伪代码:建立连接
try:
yield db # yield 写法支持用完自动释放
finally:
db.close()
@app.get("/items")
def list_items(db=Depends(get_db)):
return db.query_all("SELECT * FROM items")
# 依赖里再依赖:鉴权 → 用户 → 数据,按需组合
def get_current_user(token: str = Depends(oauth_scheme)):
return decode_token(token)
@app.get("/me")
def me(user=Depends(get_current_user)):
return {"user": user.username}
与 SQLAlchemy 搭配是社区标准组合:用 sessionmaker 创建会话工厂,在依赖里 yield 会话并负责提交/回滚,业务代码完全不用关心连接生命周期。测试时把 get_db 覆盖成测试库,一行代码切换环境。
中间件与鉴权
中间件在请求进入路由之前、响应离开之前执行,适合日志、CORS、限流、统一异常处理。CORS 是前后端分离最常见的配置:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://your-site.example"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
鉴权的主流做法是 OAuth2 密码流 + JWT:FastAPI 官方文档提供了完整示例,核心流程是——
- 登录接口校验用户名密码,签发 JWT(含过期时间与用户标识);
- 受保护接口从 Authorization 头取 token,验签后解析出用户;
- 把「解析当前用户」封装成依赖,接口里声明
user=Depends(get_current_user)即自动拦截。
生产级补充:密码用 bcrypt/argon2 哈希、token 设置合理过期与刷新机制、敏感操作加二次校验。鉴权逻辑集中在依赖里,路由代码保持干净。
部署与性能
开发用 uvicorn --reload,生产则要换一套姿势:多进程 + 进程管理 + 反向代理。推荐组合:
# 生产启动:多 worker 利用多核,--workers 按 CPU 核数设置
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
# 或用 Gunicorn 作为进程管理器(Linux 常用)
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker
| 关注点 | 建议 |
|---|---|
| 并发模型 | IO 密集用 async def + 异步库;CPU 密集交给线程池/独立进程 |
| 静态资源 | 交给 Nginx / CDN,不经过 Python |
| 数据库 | 连接池 + 慢查询日志 + 索引检查 |
| 容器化 | 多阶段构建,基础镜像用 python:3.12-slim |
性能自检套路:先用 /docs 确认接口行为正确,再用 Locust / wrk 压测定位瓶颈,最后针对瓶颈优化——多数时候瓶颈在数据库查询而不是框架本身。
从入门到上线的路线图
给想认真做项目的读者一条可执行的路线:
- 第 1 周:跑通 Hello World,掌握路径/查询/请求体三种参数与自动文档。
- 第 2 周:用 Pydantic 建数据模型,接入 SQLAlchemy 与数据库迁移(Alembic)。
- 第 3 周:把鉴权、日志、异常处理封装成依赖与中间件,写单元测试(TestClient)。
- 第 4 周:容器化 + 反向代理 + 监控(健康检查、访问日志、错误追踪)。
学习资源排序:官方文档(写得极好,含完整教程)→ 官方安全教程(鉴权)→ 开源项目源码。避开「一年前的博客教程」,FastAPI 迭代很快,以官方文档为最新基准。
框架的边界要心里有数:FastAPI 擅长的是 API 服务,而不是把业务规则、消息队列、定时任务全塞进路由。分层清晰的项目,框架升级时才有底气。
下一篇建议搭配阅读同频道的《Python 开发环境搭建与虚拟环境管理实战》,把开发环境的地基打好,写代码时更从容。