首页
/ FastAPI 请求体(Request Body)完整指南:用 Pydantic 模型声明、验证与自动生成文档

FastAPI 请求体(Request Body)完整指南:用 Pydantic 模型声明、验证与自动生成文档

2026-09-06 21:41:06作者:房伟宁

本篇指南基于 FastAPI 官方文档中的 Request Body 教程,讲清楚一件事:当客户端(如浏览器、curl、前端应用)需要向你的 API 发送数据时,如何用 Pydantic 模型声明 Request Body,让 FastAPI 自动完成 JSON 读取、类型转换、数据验证、OpenAPI 文档生成和编辑器补全。读完本文,你将掌握:如何用 BaseModel 定义请求体模型、如何在路径操作中直接以类型注解声明请求体、FastAPI 如何自动区分 Body/路径/Query 参数,以及这套机制在 FastAPI 源码中的实现位置。

1. 什么是 Request Body,它与 Response Body 有何区别

Request Body 是客户端发送到你的 API 的数据;Response Body 是你的 API 发送给客户端的数据。你的 API 几乎总要发送 Response Body,但客户端并不总是发送 Request Body——很多时候客户端只是请求某个路径,最多附带几个 Query 参数,但没有 Body。

在 FastAPI 中声明 Request Body 的方式是:使用 Pydantic 模型,并享受 Pydantic 提供的所有能力与优势。

注意(HTTP 方法选择)

  • 若要发送数据,建议使用 POST(最常用)、PUTDELETEPATCH 之一;
  • GET 请求中发送 Body 在 HTTP 规范中是未定义的行为。FastAPI 虽然仍支持这么做(仅限非常复杂/极端的场景),但不推荐。因此 Swagger UI 交互文档在使用 GET不会显示 Body 的文档,并且一些中间代理(Proxy)也可能不支持。

2. 第一步:导入 Pydantic 的 BaseModel

首先需要从 pydantic 导入 BaseModel,完整入口文件见 tutorial001_py310.py

from fastapi import FastAPI
from pydantic import BaseModel

3. 创建你的数据模型

将数据模型声明为一个继承自 BaseModel 的类,所有属性使用标准 Python 类型:

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

这里有两个关键约定:

  • 有默认值的属性不是必填的,没有默认值则是必填的;使用 None 可以让属性变为可选(optional);
  • 这与声明 Query 参数的规则一致:默认值决定必填性,类型注解决定校验与补全

以上面这个模型为例,它声明了一个 JSON "object"(即 Python dict),例如:

{
    "name": "Foo",
    "description": "An optional description",
    "price": 45.2,
    "tax": 3.5
}

由于 descriptiontax 是可选的(默认值为 None),下面这个 JSON object 同样合法:

{
    "name": "Foo",
    "price": 45.2
}

4. 将模型声明为路径操作的参数

把模型加入路径操作(path operation)的方式,与声明路径参数、Query 参数完全一样——直接写类型注解:

app = FastAPI()


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

参数 item 的类型注解声明为你创建的模型 Item,仅此一行代码,FastAPI 就会将其识别为 Request Body。

5. 仅凭类型声明,FastAPI 自动完成的事情

有了这一行 Python 类型声明后,FastAPI 会:

  1. 将 Request Body 作为 JSON 读取
  2. 转换相应的类型(在需要时);
  3. 验证这些数据
    • 若数据无效,返回一个清晰可读的错误,精确指出在哪里哪些数据不正确;
  4. 把收到的数据以 item 参数传递给你
    • 由于你在函数中将其声明为 Item 类型,你会获得完整的编辑器支持(自动补全等),覆盖所有属性及其类型;
  5. 为你的模型生成 JSON Schema 定义,你也可以在项目的其他地方复用这些 Schema(如果对你有意义的话);
  6. 这些 Schema 会成为生成的 OpenAPI Schema 的一部分,并被自动文档 UI(Swagger UI、ReDoc 等)使用。

源码级印证:请求体是如何被识别和读取的

从源码结构看,上述"自动识别"发生在依赖解析阶段。fastapi/dependencies/utils.py 中,当参数没有显式的 Annotated 字段信息时,FastAPI 按以下顺序推断参数类型:

if is_path_param:
    field_info = params.Path(annotation=use_annotation)
elif is_uploadfile_or_nonable_uploadfile_annotation(...) or ...:
    field_info = params.File(annotation=use_annotation, default=default_value)
elif not field_annotation_is_scalar(annotation=type_annotation):
    field_info = params.Body(annotation=use_annotation, default=default_value)
else:
    field_info = params.Query(annotation=use_annotation, default=default_value)

也就是说:与路径模板匹配的参数成为路径参数;非标量类型(如 Pydantic 模型)被推断为 Body;标量类型则被推断为 Query。请求到达时,request_body_to_argsfastapi/dependencies/utils.py)负责真正读取请求体、按模型字段验证并构造出传给端点函数的参数。这一实现与文档中"FastAPI 会正确识别每个参数并取数于正确的位置"的描述完全对应。

6. 自动文档:JSON Schema 进入 OpenAPI 与 Swagger UI

你的模型的 JSON Schema 会成为 OpenAPI 生成 Schema 的一部分,并显示在交互式 API 文档中(Schema 组件定义):

FastAPI Swagger UI 中由 Pydantic 模型 Item 自动生成的 Request Body JSON Schema 定义

并且在每个需要它的路径操作中也会被直接使用(左侧为操作定义、右侧为可编辑的请求体示例):

FastAPI Swagger UI 中 /items/ POST 操作界面,展示自动生成的 Item 请求体表单与 JSON 示例

7. 编辑器支持:类型提示与错误检测

在编辑器中,你在函数内部能获得类型提示和代码自动补全(如果你拿到的是一个 dict 而不是 Pydantic 模型,就不会有这些):

编辑器中对 item.tax 属性访问的自动补全提示,展示 Item 模型属性的类型信息

对于错误的类型操作,你还会收到错误提示:

编辑器中对非法类型操作 item.price + item.tax 的类型错误检测

这不是偶然——整个框架就是围绕这一设计构建的。这个设计在进入实现之前就在设计阶段经过了充分测试,以确保它对所有编辑器都有效;甚至 Pydantic 本身也为此做过一些修改。

提示:如果你使用 PyCharm,可以使用 Pydantic PyCharm 插件(Pydantic 社区插件),它针对 Pydantic 模型提供:代码补全、类型检查、重构、搜索、代码检查(inspections)等增强的编辑器支持。在 Visual Studio Code、PyCharm 和大多数 Python 编辑器中,你都能获得同样的编辑器支持。

8. 在操作函数中使用模型

在函数内部,你可以直接使用模型对象的所有属性。见 tutorial002_py310.py

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):
    item_dict = item.model_dump()
    if item.tax is not None:
        price_with_tax = item.price + item.tax
        item_dict.update({"price_with_tax": price_with_tax})
    return item_dict

注意示例中直接访问 item.taxitem.price——它们是强类型的模型属性;item.model_dump() 是 Pydantic v2 中将模型转为 dict 的标准方式(旧版 Pydantic v1 中对应 item.dict())。对应的行为验证见 tests/test_tutorial/test_body/test_tutorial002.py

9. Request Body + 路径参数:同时声明

你可以同时声明路径参数和 Request Body。FastAPI 会识别出:与路径参数同名的函数参数取自路径,而类型为 Pydantic 模型的函数参数取自 Request Body。见 tutorial003_py310.py

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    return {"item_id": item_id, **item.model_dump()}

这里 item_id: int 取自 URL 路径 {item_id}item: Item 取自请求体 JSON。行为验证见 tests/test_tutorial/test_body/test_tutorial003.py

10. Request Body + 路径参数 + Query 参数:三者共存

你也可以在同一操作中同时声明 Body路径Query 参数,FastAPI 会把每一处数据都从正确的位置取出来。见 tutorial004_py310.py

@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

函数参数按以下规则识别:

规则 结果
参数同时出现在 路径模板中(如 {item_id} 作为路径参数使用
参数是简单类型intfloatstrbool 等) 作为 Query 参数
参数是 Pydantic 模型类型 作为 Request Body

这条识别规则与 fastapi/dependencies/utils.pyis_path_param → 非 field_annotation_is_scalarparams.Body / params.Query 的推断逻辑一一对应。

注意:FastAPI 之所以知道 q 不是必填的,是因为它有默认值 = None。FastAPI 不会通过 str | None 这个联合类型来判断参数是否必填。但添加 str | None 类型注解可以让编辑器提供更好的支持并检测错误。

11. 不使用 Pydantic 模型:多个简单 Body 参数

如果你不想使用 Pydantic 模型,也可以直接使用 Body 参数声明多个简单类型的请求体字段。详见《Body – 多个参数:Body 中的简单值》(仓库路径:docs/de/docs/tutorial/body-multiple-params.md)。

从源码看,多个 Body 参数最终会经由 create_body_modelfastapi/dependencies/utils.py)在运行时动态合并为一个 Pydantic 模型再统一验证——也就是说,即使你不写模型类,FastAPI 底层依然在用一个 Pydantic 模型承接整个请求体。

小结与适用前提

  • 声明 Request Body 的完整链路:from pydantic import BaseModel → 继承 BaseModel 定义模型 → 在路径操作函数中用模型类型注解一个参数;
  • 发送数据优先使用 POST / PUT / DELETE / PATCH,避免 GET 携带 Body;
  • 参数来源(Body / 路径 / Query)完全由类型 + 路径模板 + 默认值决定,规则在 fastapi/dependencies/utils.py 中实现;
  • 上述示例代码(如 str | None 联合类型写法)要求 Python 3.10+,这与 docs_src/body/tutorial00*_py310.py 文件名中的 py310 标记一致;
  • 教程代码全部可在 docs_src/body/ 中查看,对应测试位于 tests/test_tutorial/test_body/,可运行 pytest 验证行为。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388