上一篇你学会了用 curl 向服务器发请求、看响应。现在换个身份——你来当服务器。FastAPI 就是帮你快速搭建 HTTP 服务器的 Python 框架。
打个比方:API 服务像一家餐厅。顾客看菜单点菜(发送 HTTP 请求),服务员把订单送到厨房(路由分发),厨师按菜谱做菜(处理函数),做完传菜出窗口(返回 HTTP 响应)。FastAPI 就是这家餐厅的运营系统——菜单自动生成(内置 API 文档),服务员自动校验订单格式(Pydantic 数据验证),厨师可以同时处理多道菜(异步支持)。
如果没有框架,你需要从零解析 HTTP 请求行、请求头、请求体,手动路由分发,处理异常,构造响应——每一步都要手写。Web 框架把这些重复劳动封装好,你只需定义"什么 URL 对应什么函数",框架自动完成剩下的工作。
| 特性 | FastAPI | Flask | Django |
|---|---|---|---|
| 异步支持 | 原生 ASGI 异步 | 需 async 扩展 | 3.1+ 部分支持 |
| 数据验证 | Pydantic 自动验证 | 手动或扩展 | Form/Serializer |
| API 文档 | 自动生成 Swagger + ReDoc | 需 Flask-RESTX 等 | 需 DRF + drf-spectacular |
| 学习曲线 | 低(会 Python 即可) | 低 | 高(全家桶概念多) |
| 性能 | 与 Node.js / Go 相当 | 中等 | 中等 |
FastAPI 的核心优势是类型驱动——你用 Python 类型提示声明参数类型,框架自动完成验证、转换、文档生成三件事。写一次类型标注,三处受益。
pip install "fastapi[standard]" 会自动装好全部依赖。了解了 FastAPI 的定位,现在动手安装。和所有 Python 项目一样,先建虚拟环境,再装依赖。
终端提示符前出现 (venv) 表示虚拟环境已激活。Termux 用户同样执行上述命令,Python 3.13+ 可直接使用。
[standard] 后缀会额外安装 Uvicorn(ASGI 服务器)、python-multipart(表单解析)等开发常用依赖。截至 2026 年 8 月,FastAPI 最新稳定版为 0.139.x,Pydantic 为 v2。
预期输出:
看到版本号即安装成功。版本号可能更高,只要以 0.1 开头都说明是 FastAPI 2.x 时代前的版本(当前尚未发布 2.0)。
环境就绪,写第一个 API。在项目目录下创建 main.py,输入以下 6 行代码:
逐行拆解这 6 行代码做了什么:
from fastapi import FastAPI — 导入 FastAPI 类,它是整个应用的核心
app = FastAPI() — 创建应用实例,所有路由都注册到这个对象上
@app.get("/") — 装饰器,声明这个函数处理 GET 请求,路径是根路径 /
def read_root(): — 处理函数,函数名会出现在自动文档中
return {"message": "Hello, FastAPI!"} — 返回字典,FastAPI 自动转为 JSON 响应
FastAPI 自带 CLI 命令,在项目目录下执行:
终端输出:
fastapi dev 会自动找到 main.py 中的 app 变量,用 Uvicorn 启动开发服务器,并开启热重载——你修改代码保存后服务器自动重启。
也可以用传统命令:uvicorn main:app --reload。其中 main:app 表示"main.py 文件中的 app 变量",--reload 开启热重载。
开一个新终端窗口(保持服务器运行),用上一篇学过的 curl 发请求:
响应:
你返回的 Python 字典 {"message": "Hello, FastAPI!"} 被 FastAPI 自动转换成了 JSON 响应。响应头中 content-type 自动设为 application/json——上一篇学过的 HTTP 知识在这里派上了用场。
Hello World 只返回固定内容。真实的 API 需要接收用户传入的参数。FastAPI 从函数签名中自动提取参数——路径中的变量变成路径参数,URL 问号后的变量变成查询参数。
在 URL 路径中用花括号 {} 声明变量,函数参数名与花括号内的名称对应:
注意 user_id: int 的类型标注。FastAPI 会自动把 URL 中的字符串转为 int,如果转换失败直接返回 422 错误:
不在路径花括号中的函数参数,FastAPI 自动当作查询参数。用默认值声明可选参数:
测试不同 URL 的效果:
& 等特殊字符时,curl 需要用引号包裹整个 URL,否则 shell 会把 & 解释为后台运行符。Python 3.10+ 的类型标注 str | None 等价于 Optional[str],但更简洁。GET 请求通过 URL 传参够了,但 POST/PUT 请求需要发送结构化数据(JSON 请求体)。FastAPI 用 Pydantic 模型自动解析和验证请求体——你定义数据结构,框架负责校验。
Field(...) 中的 ... 表示必填(Ellipsis),default=1 表示有默认值。ge(greater than or equal)和 le(less than or equal)限定数值范围。
发送合法数据:
发送非法数据(priority 超出范围):
FastAPI 自动返回 422 状态码和详细错误信息,告诉你哪个字段出了什么问题。不需要手写任何 if title is None 或 if priority > 5 的校验代码。
Content-Type 头,FastAPI 不知道请求体是 JSON,返回 422-H "Content-Type: application/json" 头前面分块学了路径参数、查询参数、请求体验证。现在把它们组合起来,实现一个完整的待办事项(Todo)CRUD API——增删改查四件套,对应 HTTP 的 POST/DELETE/PUT/GET。
为了聚焦 FastAPI 本身,本篇用内存列表存储数据(重启后丢失)。第 14 篇会接入 PostgreSQL 数据库实现持久化。
用以下内容替换 main.py(共约 45 行):
| 方法 | 路径 | 功能 | 状态码 |
|---|---|---|---|
| GET | /todos |
获取全部待办 | 200 |
| POST | /todos |
创建新待办 | 201 |
| GET | /todos/{id} |
获取单个待办 | 200 / 404 |
| PUT | /todos/{id} |
更新待办内容 | 200 / 404 |
| DELETE | /todos/{id} |
删除待办 | 204 / 404 |
保存代码后服务器自动重载,依次执行以下命令体验完整流程:
DELETE 请求加 -i 可以看到状态行 HTTP/1.1 204 No Content——上一篇学过的 204 表示"成功但无返回体"。
response_model 参数控制响应体结构——即使内部返回多余的字典字段,FastAPI 也只输出 model 中声明的字段。这叫"响应过滤",防止意外泄露内部数据。TodoCreate 是输入模型(用户提交什么),TodoResponse 是输出模型(API 返回什么),分开定义让接口更安全。写完 CRUD 代码,FastAPI 已经根据你的路由和 Pydantic 模型自动生成了两套交互式 API 文档——不需要任何额外配置或注解。
浏览器打开 http://127.0.0.1:8000/docs,你会看到所有 API 端点按方法分组排列,每个端点显示路径、HTTP 方法、请求参数结构和响应模型。
操作流程:
POST /todos 端点,展开详情
Try it out 按钮
Execute 发送请求
打开 http://127.0.0.1:8000/redoc,ReDoc 提供更适合阅读的三栏式文档——左侧目录、中间详情、右侧示例。适合生成对外发布的 API 参考文档。
底层支撑两套文档的是 http://127.0.0.1:8000/openapi.json——一份符合 OpenAPI 规范的 JSON 描述文件。它记录了所有端点、参数、模型、响应结构。前后端团队可以基于这份 JSON 自动生成前端请求代码、Mock 服务器或其他语言的客户端 SDK。
"""获取全部待办事项。支持分页参数 skip 和 limit。""" 这样的描述会出现在 Swagger UI 的端点说明区域,让团队协作时接口用途一目了然。GET /todos/{todo_id}/toggle 端点,将指定待办的 completed 字段在 True/False 之间切换,并返回更新后的待办。用 curl 或 Swagger UI 测试。GET /todos 端点添加 skip 和 limit 查询参数,返回分页后的列表。同时添加 priority 查询参数实现按优先级筛选。