FastAPI 入门,先搞懂一个请求是怎么跑起来的
学 FastAPI 最容易卡住的地方,不是语法。
真正容易卡住的是,你明明只写了一个 Python 函数,为什么浏览器一访问 URL,它就能跑起来;为什么函数返回一个字典,浏览器收到的却是 JSON;为什么 /docs 页面还能自动生成接口文档。
如果这个链路没想清楚,后面学 Path、Query、Pydantic、依赖注入、ORM,都会像在背零散知识点。
所以这一篇先不急着堆功能,我们先把 FastAPI 的第一条主线讲清楚。
一个 HTTP 请求,到底是怎么进入 FastAPI,又怎么变成响应返回给客户端的。
本篇准备
如果你想跟着跑代码,先安装 FastAPI 和 Uvicorn:
pip install fastapi uvicorn
本文示例默认你把代码写在 main.py 里,然后用下面的命令启动:
uvicorn main:app --reload
启动成功后,浏览器访问 http://127.0.0.1:8000/ 就能看到接口返回。
1. 最小 FastAPI 应用
一个最小 FastAPI 应用大概长这样:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
运行它:
uvicorn main:app --reload
这里有三个关键点:
| 写法 | 含义 |
|---|---|
main |
Python 文件名,也就是 main.py |
app |
文件里的 FastAPI 应用实例 |
--reload |
开发模式下代码变化自动重启 |
启动后访问:
http://127.0.0.1:8000/
你会看到:
{
"message": "Hello World"
}
这个例子看着简单,但它已经包含了 FastAPI 最核心的工作方式。
2. FastAPI 做的第一件事,建立 URL 和函数的映射
这行代码:
@app.get("/")
不是普通装饰器那么简单。它告诉 FastAPI:
如果客户端用 GET 方法访问 /,就执行下面这个函数。
也就是说,FastAPI 的路由关系由两部分决定:
- HTTP 方法,比如
GET、POST、PUT、DELETE - URL 路径,比如
/、/hello、/news/list
可以把它想成一张路由表:
| 请求方法 | 请求路径 | 处理函数 |
|---|---|---|
GET |
/ |
root() |
GET |
/hello |
get_hello() |
POST |
/register |
register() |
用 Mermaid 画出来就是这样:
读 FastAPI 代码时,先看装饰器,再看函数名和参数。
装饰器决定这个函数负责哪个接口。
3. 为什么返回 dict 会变成 JSON
在 Flask 或 Django 里,你可能经常需要显式返回响应对象。
但 FastAPI 里,很多时候你只需要返回 Python 对象:
@app.get("/user")
async def get_user():
return {
"id": 1,
"name": "Tom"
}
FastAPI 会自动把字典、列表、Pydantic 模型等对象转换成 JSON 响应。
也就是说,你写的是 Python 数据结构,客户端收到的是 HTTP 响应。
这件事对新手很重要,因为它把 API 开发里最常见的工作简化了:
当然,后面我们还会讲 HTMLResponse、FileResponse、response_model,那是响应系统的进阶部分。
这一篇先记住一件事:
普通 API 接口里,返回 dict/list/model,FastAPI 默认会帮你转成 JSON。
4. /docs 为什么能自动生成
FastAPI 很大的一个优势,是自动生成交互式 API 文档。
启动服务后访问:
http://127.0.0.1:8000/docs
会看到 Swagger UI。
访问:
http://127.0.0.1:8000/redoc
会看到 ReDoc。
这个能力不是魔法,来源主要有三块:
- 路由装饰器,比如
@app.get("/book/{id}") - Python 类型注解,比如
id: int - Pydantic 模型,比如请求体和响应模型
FastAPI 会根据这些信息生成 OpenAPI schema,再由 Swagger UI 或 ReDoc 渲染成页面。
所以你写类型注解,不只是给 Python 或编辑器看的,也是给 API 文档和参数校验看的。
5. 同步函数和异步函数
FastAPI 同时支持普通函数和异步函数:
@app.get("/sync")
def sync_api():
return {"mode": "sync"}
@app.get("/async")
async def async_api():
return {"mode": "async"}
很多人一开始会把 async 理解成更快。
这个理解不准确。
更准确的说法是,async 适合处理 I/O 等待。
比如数据库查询、网络请求、Redis 读取,这些操作经常不是 CPU 在算,而是在等外部系统返回。异步函数可以在等待期间把执行权让出来,让服务继续处理别的请求。
但如果你在 async def 里写阻塞代码,比如:
import time
@app.get("/bad")
async def bad_api():
time.sleep(3)
return {"ok": True}
这就会卡住事件循环。
正确的方向是,要么使用真正的异步库,要么把阻塞任务放到合适的位置处理。
课程里后面使用 SQLAlchemy Async、aiomysql、redis.asyncio,原因就在这里。
6. 从请求到响应的完整链路
把前面的内容合起来,一次请求大概会经历这些步骤:
这里先认识几个名字:
| 名称 | 作用 |
|---|---|
| Uvicorn | ASGI 服务器,负责运行 FastAPI 应用 |
| FastAPI app | 应用对象,管理路由、中间件、异常处理 |
| Router | 路由匹配,把 URL 分发给函数 |
| Handler | 具体路径操作函数,也就是你写的业务函数 |
| Response | 最终返回给客户端的 HTTP 响应 |
后面所有知识点,几乎都能塞进这条链路里。
Path、Query、Body 属于参数解析。
Pydantic 属于数据校验和序列化。
Middleware 属于请求进入和响应返回时的外层处理。
Depends 属于执行函数前准备资源。
ORM 属于函数内部访问数据库。
7. 小结
FastAPI 入门不要先背 API。
先记住这条线:
客户端请求 -> Uvicorn -> FastAPI 路由 -> 参数解析 -> 函数执行 -> JSON 响应
只要这条线清楚,后面的知识点就不散。
你看到 @app.get(),就知道这是在登记路由。
你看到 id: int,就知道 FastAPI 会做类型转换和校验。
你看到 return {"ok": True},就知道它会被转成 JSON 响应。
这就是 FastAPI 最核心的入门心智模型。
下一篇,我们顺着参数解析继续往下讲,Path、Query、Body 到底怎么区分。
参考资料
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)