当前位置: 首页 > news >正文

FastAPI 参数详解:路径参数、查询参数与请求体 —— 从入门到实战

【学习记录】FastAPI 参数详解:路径参数、查询参数与请求体 —— 从入门到实战

FastAPI 是一款现代、高性能的 Python Web 框架,凭借自动类型转换、数据验证和 OpenAPI 文档生成等特性,迅速成为 API 开发的首选。本文系统讲解 FastAPI 中三种最核心的参数传递方式——路径参数查询参数请求体,从基础用法到进阶验证,从混合使用到嵌套模型,辅以完整的代码示例和测试命令,帮助你全面掌握 FastAPI 的参数处理机制。


📌 目录

  1. 路径参数(Path Parameters)
    • 1.1 基础用法:类型注解自动转换
    • 1.2 进阶:使用Path添加验证与元数据
  2. 查询参数(Query Parameters)
    • 2.1 基础用法:类型注解 + 默认值
    • 2.2 必填查询参数
    • 2.3 使用Query添加验证和描述
    • 2.4 列表参数(多值)
    • 2.5 布尔类型参数
  3. 请求体(Request Body)
    • 3.1 使用 PydanticBaseModel定义数据结构
    • 3.2 使用Field添加验证和描述
    • 3.3 在路径操作函数中使用请求体
    • 3.4 混合使用:路径参数 + 查询参数 + 请求体
    • 3.5 嵌套模型与复杂结构
  4. 完整实战示例
  5. 总结

一、路径参数(Path Parameters)

路径参数是 URL 路径的一部分,用于唯一标识资源,例如/items/42中的42。FastAPI 通过类型注解自动解析、转换和验证路径参数,并提供Path类来添加额外的元数据、验证规则和文档描述。

1.1 基础用法:类型注解自动转换

只需在函数参数中声明与路径变量同名的参数,并标注类型,FastAPI 会自动:

  • 从路径中提取对应值
  • 转换为声明的类型(如intfloatstr
  • 若转换失败或不符合类型,自动返回清晰的错误信息
fromfastapiimportFastAPI app=FastAPI()@app.get("/items/{item_id}")asyncdefget_item(item_id:int):# 类型注解 intreturn{"item_id":item_id,"message":f"商品{item_id}"}

测试

# 正常访问curlhttp://127.0.0.1:8000/items/42# 输出: {"item_id":42,"message":"商品 42"}# 类型错误curlhttp://127.0.0.1:8000/items/abc# 输出: 422 错误,提示 item_id 应为整数

1.2 进阶:使用Path添加验证与元数据

Path是 FastAPI 提供的函数,用于为路径参数附加额外信息,例如:

  • 标题(title):文档中显示的名称
  • 描述(description):参数说明
  • 验证规则gt(大于)、ge(大于等于)、lt(小于)、le(小于等于)、regex(正则表达式)等
  • 示例值(example):生成文档时的示例
  • 废弃标记(deprecated)
fromfastapiimportFastAPI,Path app=FastAPI()@app.get("/items/{item_id}")asyncdefget_item(item_id:int=Path(title="商品ID",description="必须是大于 0 的整数,用于唯一标识商品",gt=0,example=123)):return{"item_id":item_id}

测试

# 传入 0 或负数,触发验证错误curlhttp://127.0.0.1:8000/items/0# 输出: 422 错误,{"detail":[{"type":"greater_than","msg":"Input should be greater than 0",...}]}

在生成的 OpenAPI 文档(/docs)中,会显示参数名称、类型、描述和示例值。


二、查询参数(Query Parameters)

查询参数是 URL 中?后面以key=value形式传递的参数,常用于过滤、排序、分页等可选操作。FastAPI 通过函数参数的类型注解自动识别查询参数,并支持使用Query类添加验证和元数据。

2.1 基础用法:类型注解 + 默认值

直接在路径操作函数中定义非路径参数,并给予默认值(可选)或没有默认值(必填)。FastAPI 会自动从查询字符串中提取同名参数。

fromfastapiimportFastAPI app=FastAPI()@app.get("/items/")asyncdeflist_items(limit:int=10,skip:int=0):return{"limit":limit,"skip":skip}

测试

# 使用自定义值curl"http://127.0.0.1:8000/items/?limit=5&skip=10"# 输出: {"limit":5,"skip":10}# 不传参数,使用默认值curl"http://127.0.0.1:8000/items/"# 输出: {"limit":10,"skip":0}

2.2 必填查询参数

去掉默认值,则该查询参数为必填项。

@app.get("/users/")asyncdefget_users(name:str):# 没有默认值,必填return{"name":name}

测试

# 缺少必填参数curl"http://127.0.0.1:8000/users/"# 输出: 422 错误# 正确curl"http://127.0.0.1:8000/users/?name=alice"

2.3 使用Query类添加验证和描述

Query用于为查询参数附加额外信息:标题、描述、默认值、验证规则(min_lengthmax_lengthregexgtgeltle)、废弃标记等。

fromfastapiimportFastAPI,Query app=FastAPI()@app.get("/items/")asyncdeflist_items(limit:int=Query(10,ge=1,le=100,description="每页数量"),skip:int=Query(0,ge=0,title="偏移量"),q:str=Query(None,max_length=50,regex="^[a-zA-Z0-9]+$")):return{"limit":limit,"skip":skip,"q":q}

测试

# 超出范围curl"http://127.0.0.1:8000/items/?limit=200"# 422 错误# 正则不匹配curl"http://127.0.0.1:8000/items/?q=hello!"# 422 错误

2.4 查询参数中的列表(多值)

使用List类型或Querydefault参数接收多个相同名称的参数。

fromtypingimportListfromfastapiimportFastAPI,Query app=FastAPI()@app.get("/items/")asyncdeflist_items(tags:List[str]=Query(["all"])):return{"tags":tags}

测试

curl"http://127.0.0.1:8000/items/?tags=python&tags=fastapi"# 输出: {"tags":["python","fastapi"]}curl"http://127.0.0.1:8000/items/"# 输出: {"tags":["all"]}

2.5 布尔类型查询参数

布尔值支持多种真值表示:trueTrue1onyes视为TruefalseFalse0offno视为False

@app.get("/users/")asyncdefget_users(active:bool=True):return{"active":active}

测试

curl"http://127.0.0.1:8000/users/?active=false"# 输出: {"active":false}

三、请求体(Request Body)

请求体用于传输客户端向服务器发送的复杂数据,例如创建资源时的 JSON 对象。FastAPI 通过Pydantic 模型来声明请求体的数据结构,并自动完成解析、验证和文档生成。

3.1 使用 PydanticBaseModel定义数据模型

BaseModel是 Pydantic 提供的基础类,用于定义数据结构和验证规则。

frompydanticimportBaseModelclassItem(BaseModel):name:strprice:floatis_available:bool=True# 带默认值,可选字段
  • 每个属性通过类型注解声明字段类型。
  • 有默认值的字段为可选(请求时可不提供),无默认值的字段为必填。
  • 当客户端发送的 JSON 不符合类型要求时,FastAPI 会自动返回 422 错误。

3.2 使用Field添加验证和描述

Field是 Pydantic 提供的函数,可为字段附加额外的元数据和验证规则:默认值、标题、描述、gtgeltlemin_lengthmax_lengthregex、示例值等。

frompydanticimportBaseModel,FieldclassItem(BaseModel):name:str=Field(...,title="商品名称",max_length=50,example="智能手机")price:float=Field(...,gt=0,le=10000,description="价格,必须为正数且不超过10000")is_available:bool=Field(default=True,title="是否上架")tags:list[str]=Field(default=[],max_items=5)
  • ...表示该字段是必填的(...是 Python 的Ellipsis对象,Pydantic 约定用于表示没有默认值)。
  • 如果不提供默认值且不使用...,字段也是必填的,但推荐使用...以明确表达意图。

3.3 在路径操作函数中使用请求体

只需将模型类型作为参数声明,FastAPI 就会自动从请求体中读取 JSON 并转换为该模型实例。

fromfastapiimportFastAPIfrompydanticimportBaseModel,Field app=FastAPI()classItem(BaseModel):name:str=Field(...,min_length=1,max_length=50)price:float=Field(...,gt=0)is_available:bool=True@app.post("/items/")asyncdefcreate_item(item:Item):return{"message":f"商品{item.name}创建成功","item":item.dict()}

测试

curl-XPOST"http://127.0.0.1:8000/items/"\-H"Content-Type: application/json"\-d'{"name":"平板电脑","price":3999.99,"stock":10}'# 输出: {"message":"商品 平板电脑 创建成功","item":{"name":"平板电脑","price":3999.99,"is_available":true}}

3.4 混合使用:路径参数 + 查询参数 + 请求体

FastAPI 能自动区分不同类型的参数:路径参数、查询参数和请求体,无需额外标记。

fromfastapiimportFastAPI,Path,QueryfrompydanticimportBaseModel,Field app=FastAPI()classItem(BaseModel):name:strprice:float=Field(...,gt=0)@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int=Path(...,gt=0),# 路径参数q:str=Query(None,max_length=10),# 查询参数item:Item=None# 请求体):return{"item_id":item_id,"query":q,"item":item}

测试

curl-XPUT"http://127.0.0.1:8000/items/42?q=urgent"\-H"Content-Type: application/json"\-d'{"name":"游戏机","price":2999.99}'# 输出: {"item_id":42,"query":"urgent","item":{"name":"游戏机","price":2999.99}}

3.5 嵌套模型与复杂结构

Pydantic 支持嵌套模型、列表、字典等复杂类型。

frompydanticimportBaseModel,FieldfromtypingimportListclassSubItem(BaseModel):sub_name:strcount:int=Field(...,ge=1)classMainItem(BaseModel):id:intdetails:SubItem tags:List[str]=[]

请求体示例

{"id":100,"details":{"sub_name":"配件","count":3},"tags":["电子","促销"]}

四、完整实战示例

以下是一个整合了路径参数、查询参数、请求体,并包含完整验证和错误处理的示例:

fromfastapiimportFastAPI,status,Path,QueryfrompydanticimportBaseModel,FieldfromtypingimportOptional,List app=FastAPI(title="商品管理API",description="演示路径参数、查询参数和请求体")# ---------- 数据模型 ----------classItemCreate(BaseModel):name:str=Field(...,min_length=1,max_length=100,example="笔记本电脑")price:float=Field(...,gt=0,le=99999,example=5999.99)stock:int=Field(0,ge=0,description="库存数量")tags:List[str]=Field(default=[],max_items=10)classItemUpdate(BaseModel):name:Optional[str]=Field(None,min_length=1,max_length=100)price:Optional[float]=Field(None,gt=0,le=99999)stock:Optional[int]=Field(None,ge=0)# ---------- 端点 ----------@app.post("/items/",status_code=status.HTTP_201_CREATED)asyncdefcreate_item(item:ItemCreate):# 模拟数据库保存return{"message":"商品创建成功","item":item.dict()}@app.get("/items/{item_id}")asyncdefget_item(item_id:int=Path(...,gt=0,title="商品ID"),include_stock:bool=Query(False,description="是否返回库存信息")):# 模拟从数据库查询item_data={"id":item_id,"name":"示例商品","price":99.99,"stock":10}ifnotinclude_stock:item_data.pop("stock")returnitem_data@app.put("/items/{item_id}")asyncdefupdate_item(item_id:int=Path(...,gt=0),update_data:ItemUpdate=None,q:str=Query(None,max_length=20)):# 模拟更新return{"item_id":item_id,"query":q,"updated_fields":update_data.dict(exclude_unset=True)ifupdate_dataelse{}}@app.delete("/items/{item_id}")asyncdefdelete_item(item_id:int=Path(...,gt=0),permanent:bool=Query(False,description="是否永久删除")):return{"item_id":item_id,"permanent":permanent,"message":"删除成功"}# ---------- 高级查询:列表参数 ----------@app.get("/search/")asyncdefsearch_items(q:str=Query(...,min_length=1,description="搜索关键词"),category:List[str]=Query([],description="分类过滤,可多个")):return{"query":q,"categories":category}

测试命令示例

# 创建商品curl-XPOST"http://127.0.0.1:8000/items/"-H"Content-Type: application/json"-d'{"name":"手机","price":2999.99,"stock":50,"tags":["电子","促销"]}'# 查询商品(不返回库存)curl"http://127.0.0.1:8000/items/1"# 查询商品(返回库存)curl"http://127.0.0.1:8000/items/1?include_stock=true"# 搜索(多分类)curl"http://127.0.0.1:8000/search/?q=手机&category=电子&category=数码"

五、总结

参数类型位置典型用途声明方式验证工具
路径参数URL 路径中/{param}资源标识(如 ID)函数参数 + 类型注解Path
查询参数URL?key=value过滤、排序、分页函数参数 + 默认值Query
请求体HTTP 请求体(JSON)创建/更新资源Pydantic 模型BaseModel+Field

核心优势

  • ✅ 自动类型转换与验证,减少手动检查代码。
  • ✅ 自动生成 OpenAPI 文档(/docs),前后端联调高效。
  • ✅ 支持复杂嵌套结构,易于扩展。
  • ✅ 路径参数、查询参数、请求体可自由混合使用,框架自动区分。

掌握这三类参数,你就能轻松构建出健壮、规范、易维护的 FastAPI 应用程序。下一步可以学习依赖注入中间件后台任务,让你的 API 更加专业。

http://www.jsqmd.com/news/933459/

相关文章:

  • 2026年银川劳动纠纷律师推荐:5位实战经验丰富的专业选择 - 本地品牌推荐
  • 从“休眠”到“唤醒”:深入解读LIN总线网络管理与AUTOSAR LinSM状态机实战
  • 为什么选择T3Q-ko-solar-dpo-v3.0-openmind?韩国AI开发者必知的7大核心优势 [特殊字符]
  • 别再傻傻用GPIO模拟了!STM32F407硬件IIC实战:驱动OLED屏幕完整流程(附代码)
  • 从CT原始DICOM到4K手术教学动画:Sora 2端到端工作流仅需22分钟——华西医院介入科实测全链路拆解
  • Python 闭包与装饰器从入门到精通(一)
  • 2026年质量好的挂钩磁铁/耐高温磁铁/包胶磁铁优质供应商推荐 - 品牌宣传支持者
  • 手把手教你用带参数的FC写一个‘万能’星三角启动程序(附TIA Portal V18程序截图)
  • 拆解Geant4模拟内核:Run、Event、Step、Track到底怎么工作?给初学者的可视化解读
  • 如何快速拯救B站缓存视频:m4s转MP4的完整指南
  • UE5 C++新手必看:别再蓝图拖拽了,手把手教你用代码搞定GameMode核心配置
  • 3步实现京东秒杀成功率翻倍:智能抢购工具实战指南
  • 从SAM到FastSAM:揭秘那个让分割模型变‘快’的1.1B数据集的秘密
  • 别再傻傻焊板子了!用嘉立创EDA标准版免费仿真,5分钟验证电路可行性
  • 2026年质量好的无锡激光清洗机/无锡清洗机/清洗机高口碑品牌推荐 - 行业平台推荐
  • 告别手忙脚乱!用Seqtk v1.4轻松搞定FASTQ/FASTA格式转换与序列提取
  • 别再傻傻焊板子了!用嘉立创EDA标准版免费仿真,帮你省下90%的硬件调试时间
  • OpenAI加持的Figure 01机器人,真能像人一样干活了?我用实测视频告诉你答案
  • PTA编程题解:C语言实现一个‘无优先级’的简单计算器(附完整代码与测试用例)
  • 告别摄像头局限:用激光雷达做行人重识别,ReID3D实战配置与效果实测
  • 从BMP文件头到像素遍历:手把手教你用C语言解析一张图片的完整数据
  • UE5 C++ 游戏模式配置全攻略:告别蓝图,从零手写你的第一个GameMode
  • 量子计算中SPAM误差分离表征技术解析
  • 个人Linux操作系统学习笔记6 - 操作系统与进程初识
  • 机器学习40讲-32:从有限到无限高斯过程
  • 新手必看:用Keil5给C51单片机写第一个按键程序,点亮你的LED灯
  • 微信小程序开发(week7
  • AI 内容泛滥时代,技术驱动型品牌如何构建可信的 “活人感“ 运营体系
  • 基于OpenCode的Harness架构实战v2.2(windows系统)
  • 被格式逼哭的毕业生,终于被 Paperxie 智能排版 “救” 了