「FastAPI & SQLAlchemy 实战」系列共 10 篇,从协程基础讲到数据库接口。这是第 7 篇。
结论:POST/PUT 的 JSON 数据用 Pydantic 模型接收;项目变大后,用 APIRouter 按模块拆路由,主应用只负责挂载。
一、请求体:用 BaseModel 定义结构
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
desc: str | None = None
price: float
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
发送 JSON:
curl -s -X POST http://127.0.0.1:8000/items/ \
-H "Content-Type: application/json" \
-d '{"name":"键盘","price":299}'
FastAPI 会做三件事:解析 JSON、按模型校验、把结果注入 item 参数。缺 name 或 price 返回 422,desc 可以省略。
二、请求体、路径、查询怎么区分
- Pydantic 模型参数:请求体;
- 路径里出现的
{name}:路径参数; - 其他基础类型参数:查询参数。
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, notify: bool = False):
return {"item_id": item_id, "item": item, "notify": notify}
item_id 来自路径,item 来自 JSON body,notify 来自查询字符串。
三、APIRouter:按模块拆路由
myproject/
├── main.py
└── routers/
├── user.py
└── item.py
# routers/user.py
from fastapi import APIRouter
router = APIRouter(prefix="/users", tags=["用户管理"])
@router.get("/")
def list_users():
return {"message": "用户列表"}
@router.get("/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id}
# main.py
from fastapi import FastAPI
from routers import user, item
app = FastAPI(title="路由拆分示例")
app.include_router(user.router)
app.include_router(item.router)
prefix 统一加路径前缀,tags 让 /docs 按模块分组。子路由里不要再重复写 /users。
四、验证
curl -s http://127.0.0.1:8000/users/
curl -s http://127.0.0.1:8000/users/10
curl -s http://127.0.0.1:8000/items/100
# 打开 /docs,应看到「用户管理」「商品管理」两组
五、常见错误
- 把请求体模型写成普通参数:FastAPI 会当成查询参数;
- 子路由和主应用重复加前缀:路径变成
/users/users/; - 忘记
include_router:接口 404; - 模型字段没有默认值:请求体必须传,否则 422。
下一篇
接口层讲完,下一篇进入数据库:SQLAlchemy 的 ORM、Engine、Session,以及怎么把模型映射成表。
上一篇:路径参数与查询参数 | 下一篇:SQLAlchemy 入门

AI项目博客






