FastAPI请求体怎么定义和使用?

文章导读
请求体是客户端发送给 API 的数据。当你需要从客户端接收 JSON 数据时,使用请求体来传递。FastAPI 使用 Pydantic 模型来声明请求体的结构,自动完成数据校验、转换和文档生成。
📋 目录
  1. 请求体与查询参数的区别
  2. 使用 Pydantic 模型声明请求体
  3. 实例
  4. FastAPI 对请求体的处理
  5. 使用模型属性
  6. 实例
  7. 请求体 + 路径参数
  8. 实例
  9. 请求体 + 路径参数 + 查询参数
  10. 实例
A A

FastAPI 请求体

请求体是客户端发送给 API 的数据。当你需要从客户端接收 JSON 数据时,使用请求体来传递。FastAPI 使用 Pydantic 模型来声明请求体的结构,自动完成数据校验、转换和文档生成。


请求体与查询参数的区别

数据传递方式位置适用场景HTTP 方法
路径参数URL 路径 /items/5标识资源GET、PUT、DELETE 等
查询参数URL 中 ?key=value筛选、分页等可选参数主要是 GET
请求体请求的 JSON 数据提交复杂数据POST、PUT、PATCH

发送数据应使用 POST(最常见)、PUTDELETEPATCH。虽然 FastAPI 技术上支持 GET 请求携带请求体,但这不符合 HTTP 规范,Swagger UI 也不会为 GET 请求显示请求体文档。


使用 Pydantic 模型声明请求体

1. 导入 BaseModel

from pydantic import BaseModel

2. 创建数据模型

定义一个继承 BaseModel 的类,使用 Python 标准类型声明所有属性:

实例

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


# 定义请求体数据模型
class Item(BaseModel):
    name: str               # 必填:商品名称
    description: str | None = None  # 可选:商品描述
    price: float            # 必填:商品价格
    tax: float | None = None        # 可选:税费


@app.post("/items/")
async def create_item(item: Item):
    return item

属性是否必填的规则与查询参数相同:

  • 有默认值的属性是可选的(如 descriptiontax
  • 没有默认值的属性是必填的(如 nameprice

以下 JSON 都是有效的请求体:

// 包含所有字段
{
    "name": "Foo",
    "description": "可选描述",
    "price": 45.2,
    "tax": 3.5
}

// 省略可选字段
{
    "name": "Foo",
    "price": 45.2
}

FastAPI 对请求体的处理

仅通过 Python 类型声明,FastAPI 就能自动完成以下工作:

功能说明
读取请求体以 JSON 格式读取请求中的数据
类型转换将数据转换为声明的类型(如字符串转浮点数)
数据校验校验数据有效性,无效时返回清晰的错误信息
赋值参数将校验后的数据赋值给函数参数,获得编辑器自动补全
生成文档自动生成 JSON Schema,出现在 API 文档中

使用模型属性

在路径操作函数内部,你可以像操作普通 Python 对象一样访问模型的所有属性:

实例

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None


@app.post("/items/")
async def create_item(item: Item):
    # 直接访问模型属性
    item_dict = item.model_dump()  # Pydantic v2 的序列化方法
    if item.tax:
        # 计算含税价格
        price_with_tax = item.price + item.tax
        item_dict.update({"price_with_tax": price_with_tax})
    return item_dict

Pydantic v2 使用 model_dump() 替代了 v1 的 dict() 方法来序列化模型数据。model_dump() 返回一个包含模型所有字段的字典。


请求体 + 路径参数

可以同时声明路径参数和请求体,FastAPI 会自动从正确的位置获取数据:

实例

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None


# 同时使用路径参数和请求体
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    return {"item_id": item_id, "item_name": item.name}

FastAPI 识别规则:

  • item_id 在路径 {item_id} 中出现 -> 路径参数
  • item 的类型是 Pydantic 模型 -> 请求体

请求体 + 路径参数 + 查询参数

三者可以同时使用:

实例

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None


# 同时使用路径参数、查询参数和请求体
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: str | None = None):
    result = {"item_id": item_id, **item.model_dump()}
    if q:
        result.update({"q": q})
    return result

FastAPI 的完整参数识别规则:

识别条件参数来源
参数名在路径的 {} 中声明路径参数
参数是单一类型(intstrbool 等)查询参数
参数类型是 Pydantic 模型请求体

小结

请求体的核心要点:

  • 使用 Pydantic 的 BaseModel 定义请求体结构
  • 有默认值的字段可选,没有默认值的字段必填
  • 请求体可以与路径参数和查询参数同时使用
  • FastAPI 自动完成数据校验、类型转换和文档生成
  • Pydantic v2 使用 model_dump() 进行序列化