在现代 Web 开发中,处理客户端发送的数据是 API 开发的核心任务之一。FastAPI 通过强大的请求体处理机制,让这一过程变得简单而高效。
什么是请求体?
请求体是客户端(如浏览器、移动应用等)向 API 发送的数据。当我们创建、更新或修改资源时,通常需要将结构化数据发送到服务器,这些数据就包含在请求体中。
常见的使用场景:用户注册、商品创建、数据更新等操作。
基本请求体使用
1. 定义数据模型
FastAPI 使用 Pydantic 模型来定义请求体的结构:
from fastapi import FastAPI
from pydantic import BaseModel
# 定义数据模型
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item在这个例子中:
Item类继承自BaseModel每个属性都有类型注解,支持可选参数和默认值
FastAPI 会自动将 JSON 请求体转换为
Item实例
2. 自动文档生成
FastAPI 会自动为你的请求体生成 API 文档:
访问 http://localhost:8000/docs 即可看到交互式 API 文档,其中包含请求体的详细结构。
高级请求体特性
嵌套模型
FastAPI 支持复杂的数据结构,包括嵌套模型:
from typing import List
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
tags: List[str] = []
images: List[Image] | None = None
@app.post("/items/")
async def create_item(item: Item):
return item特殊数据类型
Pydantic 支持丰富的数据类型验证:
from pydantic import EmailStr, HttpUrl
from datetime import datetime
from uuid import UUID
class User(BaseModel):
id: UUID
email: EmailStr
website: HttpUrl | None = None
created_at: datetime
age: int = Field(gt=0, le=150) # 年龄必须在 0-150 之间多种请求体参数
1. 单一请求体
@app.post("/items/")
async def create_item(item: Item):
return item2. 请求体 + 路径参数
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_id": item_id, **item.dict()}3. 请求体 + 路径参数 + 查询参数
@app.put("/items/{item_id}")
async def update_item(
item_id: int,
item: Item,
q: str | None = None
):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result多请求体参数
多个模型
class Item(BaseModel):
name: str
description: str | None = None
class User(BaseModel):
username: str
email: str
@app.post("/items/{item_id}")
async def create_item(
item_id: int,
item: Item,
user: User,
importance: int = Body(gt=0)
):
return {
"item_id": item_id,
"item": item,
"user": user,
"importance": importance
}嵌入单个请求体参数
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(embed=True)):
return {"item_id": item_id, "item": item}