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

新手必看:FastAPI 参数接收的正确姿势(路径 / 查询 / 请求体全解析)

继上一篇《FastAPI 零基础入门:从安装到快速搭建 Web 接口》之后,本篇聚焦 FastAPI 最核心的参数接收能力 —— 路径参数、查询参数、请求体,用(大白话 + 实操代码 + 可视化测试)的方式拆解,新手跟着敲代码就能懂,掌握后就能实现真正的 “数据交互型接口”。

前言

上一篇我们学会了搭建基础接口和四种请求方法,但实际开发中,接口不可能只返回固定数据:比如根据用户 ID 查信息、分页查询列表、提交用户注册信息… 这些都需要前端给后端传数据,而 FastAPI 接收前端数据的核心方式就是路径参数查询参数请求体,这也是新手从 “写死数据” 到 “动态交互” 的关键一步。

前置准备

确保你已经完成:

  1. 安装 FastAPI 和 uvicorn(pip install fastapi uvicorn);
  2. 熟悉基础的 FastAPI 项目结构和启动方式;
  3. 保留上一篇的 main.py 文件,本篇代码都基于这个文件迭代。

1 路径参数:从URL路径中取数据

1.1.什么是路径参数?

简单来说:把参数直接写在接口URL的路径里,比如想根据用户ID查询信息,接口地址设计成/user/1(1就是用户ID),这个1就是路径参数。
核心场景:查询 / 操作;指定唯一资源(如用户 ID、商品 ID、文章 ID)。

1.2.基础实操:获取单个用户ID

打开main.py,编写如下代码:

fromfastapiimportFastAPIimportuvicorn app=FastAPI()# 路径参数核心语法:@app.get("/路径/{参数名}")@app.get("/user/{user_id}",summary="根据用户ID查询用户信息")defget_user_by_id(user_id:int):# 这里指定类型int,FastAPI会自动校验!# 模拟根据ID查数据(实际开发中可对接数据库)return{"code":200,"msg":"查询成功","data":{"user_id":user_id,# 直接使用路径参数"username":f"用户{user_id}","age":18+user_id%10# 简单动态生成年龄}}if__name__=='__main__':uvicorn.run("main:app",host="127.0.0.1",port=8000,reload=True)

1.3.测试与关键知识点

第一步:启动服务
点击 PyCharm 运行按钮,启动 main.py,确保服务正常。
第二步:访问接口
打开浏览器,访问:http://127.0.0.1:8000/user/5
返回结果如下:

新手必看知识点:

  1. 类型注解的作用:如果访问http://127.0.0.1:8000/user/abc(传字符串),FastAPI 会自动返回 422 错误,无需手动写校验代码;
  2. 参数名要一致:装饰器里的{user_id}必须和函数参数user_id同名;
  3. 支持多种类型:除了 int,还支持 str、float、bool 等,比如/article/{article_title:str}。

2 查询参数:URL中?后面的键值对

2.1.什么是查询参数?

简单说:在 URL 末尾用?参数名=值的形式传参,多个参数用&分隔,比如/goods?page=1&size=10(page 是页码,size 是每页条数)。
核心场景:筛选、分页、模糊查询;(如列表分页、多条件筛选商品)

2.2. 基础实操:商品列表分页查询

代码如下:

fromfastapiimportFastAPIimportuvicorn app=FastAPI()# 查询参数:无需在路径中写,函数直接接收参数即可@app.get("/goods",summary="商品列表分页查询")defget_goods_list(page:int=1,# 默认值:如果前端不传,默认查第1页size:int=10# 默认值:如果前端不传,默认每页10条):# 模拟分页数据(实际开发中根据page和size查数据库)goods=[]foriinrange(size):goods.append({"goods_id":(page-1)*size+i+1,"goods_name":f"商品{(page-1)*size+i+1}","price":99.9+i})return{"code":200,"msg":"查询成功","data":{"page":page,"size":size,"total":100,# 模拟总条数"goods_list":goods}}if__name__=='__main__':uvicorn.run("main:app",host="127.0.0.1",port=8000,reload=True)

2.3.测试与关键知识

  • 不传参数:访问http://127.0.0.1:8000/goods,默认使用page=1&size=10;
  • 传参数:访问http://127.0.0.1:8000/goods?page=2&size=5,返回第 2 页、每页 5 条数据;
    返回结果:如图

    新手必看知识点:
  1. 查询参数无需在路径中定义:函数参数直接写,FastAPI 会自动从 URL 的?后解析;
  2. 默认值的作用:前端不传参时使用默认值,避免报错;
  3. 混合使用:路径参数和查询参数可以一起用,比如/user/{user_id}/orders?page=1&size=10(根据用户 ID 查订单,同时分页)。

3 请求体:POST/PUT 请求传“大量数据”

3.1.什么是请求体?

简单说:前端把复杂数据(如注册信息、表单数据)放在请求的 “正文” 里传参,而不是 URL 里(URL 传参有长度限制)。
核心场景:提交 / 更新大量数据;(如用户注册、提交表单、上传复杂 JSON)。
⚠️ 注意:GET 请求不支持请求体,只能用 POST/PUT 等方法。

3.2.基础实操:用户注册(POST请求+请求体)

第一步:导入 Pydantic 模型(FastAPI 的 “数据校验神器”)
FastAPI 用 Pydantic 的BaseModel定义请求体的格式,自动校验数据类型和必填项,新手不用手动写校验逻辑。
第二步:编写注册接口代码
在 main.py 中新增如下代码:

fromfastapiimportFastAPIimportuvicornfrompydanticimportBaseModel# 导入Pydantic模型app=FastAPI()# 定义请求体模型:用户注册数据格式classUserRegister(BaseModel):username:str# 必填项:用户名(字符串)password:str# 必填项:密码(字符串)age:int=18# 可选项:年龄,默认18email:str# 可选项:邮箱,可传None# POST请求+请求体:用户注册@app.post("/user/register",summary="用户注册")defuser_register(user_info:UserRegister):# 接收请求体,类型为自定义的UserRegister# 模拟注册逻辑(实际开发中可写入数据库)return{"code":200,"msg":"注册成功","data":{"username":user_info.username,"age":user_info.age,"email":user_info.emailifuser_info.emailelse"未填写"}}if__name__=='__main__':uvicorn.run("main:app",host="127.0.0.1",port=8000,reload=True)

3.3.测试请求体

请求体无法直接在浏览器访问,推荐用 FastAPI 自带的交互式文档测试:

  1. 启动服务后,访问http://127.0.0.1:8000/docs(自动生成的 Swagger 文档);
  2. 找到/user/register接口,点击「Try it out」;
  3. 编辑请求体 JSON(按模型格式填),示例:
  4. 点击 Execute,就能看到返回结果:

新手必看知识点:

  1. Pydantic 模型的作用
  • 自动校验:比如 age 传字符串会报错,username 不传会提示必填;
  • 自动解析:把前端传的 JSON 自动转成 Python 对象,直接用user_info.username取值;
  1. 可选项定义:age: int = 18(默认值)、email: str | None = None(可传 None);
  2. 请求体只支持 POST/PUT 等:GET 请求不能用,因为 GET 请求没有 “正文”。

4 三者对比:一张表看懂用法场景

类型传参位置核心场景请求方法支持示例
路径参数URL 路径中(/user/{id})唯一资源查询 / 操作(ID)所有方法/user/1、/goods/100
查询参数URL 末尾(?page=1&size=10)筛选、分页、简单条件查询所有方法(GET 常用)/goods?page=2&size=5
请求体请求正文(JSON)提交 / 更新大量复杂数据POST/PUT/ 等注册、提交表单、修改多字段

5 新手避坑指南

  1. 参数名大小写敏感:路径参数{user_id}和函数参数user_id必须完全一致;
  2. 类型注解别漏写:FastAPI 靠类型注解做自动校验,漏写会失去校验能力;
  3. GET 请求别用请求体:前端用 GET 传请求体,后端收不到,这是 HTTP 协议规定;
  4. 测试工具选对:路径参数 / 查询参数用浏览器,请求体用/docs或 Postman。

6 进阶美化!Path/Query/Field 让参数更规范

这是最简单、最实用的进阶用法,不用改逻辑,只需要加一行代码,就能让你的接口:

  • 带中文注释
  • 加参数校验(比如数字必须大于 0)
  • 接口文档更清晰
  • 一看就懂每个参数干嘛用

先安装/导入(必须做)

fromfastapiimportFastAPI,Path,Query# 路径+查询参数专用frompydanticimportBaseModel,Field# 请求体专用

6.1.路径参数+Path

作用:给路径参数加说明、限制范围

@app.get("/user/{user_id}")defget_user(# Path:给路径参数加注释 + 校验user_id:int=Path(...,description="用户ID,必须大于0",ge=1)):return{"user_id":user_id}

代表必填;ge=1代表必须 ≥ 1;description接口文档里会显示中文说明

6.2.查询参数+Query

作用:给查询参数加默认值、长度限制、范围限制

@app.get("/goods")defget_goods(page:int=Query(1,description="页码",ge=1),size:int=Query(10,description="每页数量",le=100)):return{"page":page,"size":size}

ge=1大于等于 1;le=100小于等于 100;不传就用默认值,传了自动校验

6.3.请求体+Field

作用:给请求体字段加说明、长度 / 格式校验

classUserRegister(BaseModel):username:str=Field(...,description="用户名,必填")password:str=Field(...,description="密码,至少6位",min_length=6)age:int=Field(18,description="年龄,默认18")@app.post("/user/register")defregister(user:UserRegister):returnuser

min_length=6密码最少 6 位;自动校验,不合格直接报错

三者一起用(最常用实战写法)

@app.get("/user/{user_id}/order")defget_user_order(# 路径参数user_id:int=Path(...,description="用户ID",ge=1),# 查询参数page:int=Query(1,description="页码")):return{"user_id":user_id,"page":page}

总结

本篇我们掌握了 FastAPI接收前端数据的三种核心方式以及接口参数的完整用法:
路径参数:从 URL 路径取唯一标识;用Path获取 URL 路径中的唯一标识,支持校验与文档说明;
查询参数:从 URL 末尾取筛选 / 分页条件用Query获取 URL 问号后的筛选、分页条件,可设默认值与限制;
请求体:从请求正文取复杂数据(配合 Pydantic 自动校验)。用BaseModel + Field接收复杂 JSON 数据,自动完成格式校验与字段约束。
三者搭配使用,就能覆盖绝大多数接口传参场景,让接口更规范、更健壮、文档更清晰。新手跟着代码实操一遍,并用 /docs 测试验证,就能完全掌握“前端传参、后端接收”的核心逻辑。下一篇我们将继续讲解响应模型、统一异常处理、依赖注入等实战内容,帮你写出生产级标准接口。

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

相关文章:

  • ODF配线架安装全流程实录:72芯高密度布线+光纤熔接避雷手册
  • 别再死记定义了!用Python可视化带你直观理解‘一致连续’与‘连续’的天壤之别
  • D3KeyHelper:暗黑破坏神3自动化战斗宏工具完全指南
  • 终极DayZ离线模组指南:如何免费畅享完整单机体验
  • 安装 Docker on AlmaLinux 8
  • 终极指南:如何用VTube Studio API打造智能虚拟主播互动系统 [特殊字符]
  • 算法题(滑动窗口、动态规划)
  • HardSwish激活函数改进YOLOv26高效非线性映射与计算优化双重突破
  • 终极指南:如何免费解锁惠普游戏本全部性能潜力
  • 别再手算齿轮参数了!用MATLAB脚本搞定二级减速器设计(附完整代码)
  • 别再用Keil下载了!用ST-LINK Utility给STM32烧录程序的3个隐藏技巧(附v4.6.0安装包)
  • 为什么你的Dify医疗问答系统正在悄悄泄露患者ID?——3行正则+2个中间件钩子即刻封堵
  • 数学证明不再是AI的“奢侈品”:2026奇点大会公布轻量化AGI验证套件(<2GB内存占用,支持边缘端实时验证)
  • 第三篇:Vibe Coding 深度解析(三):从 0 到 1 的落地实战指南
  • STC单片机蓝牙无线下载避坑指南:为什么你的STC15/STC8总是烧录失败?
  • KICS认知公尺完整体系:从概念到可运行的量化模型与Dashboard
  • 从STC89C51到蓝牙芯片CC2541:手把手拆解两款经典芯片,看透SOC的‘定制’内核
  • KMP与Flutter选型实战指南
  • 保姆级教程:在Ubuntu 20.04上从零部署YOLOv5+DeepSORT+C++ TensorRT目标跟踪项目(含常见编译错误解决)
  • 防串色洗衣片有用吗?解析效果、使用技巧及替代方案 - 行业分析师666
  • Windows本地开发环境救星:5分钟搞定Elasticsearch-Head与ES 8.x的联调配置(附常见跨域错误排查)
  • python helmfile
  • 从‘撸树’到报错:一个老MC玩家重拾Minecraft时遇到的OpenGL驱动坑全记录
  • 零代码创作:如何使用EPubBuilder在线编辑器快速制作专业电子书
  • 如何选择企业云盘?一张图讲清楚五大选型维度
  • Botty:暗黑破坏神II重制版像素级自动化系统的技术架构深度解析
  • 别再复制粘贴了!手把手教你用Kali Linux和Metasploit搭建Windows 10渗透测试环境(保姆级避坑)
  • 4/20
  • 如何使用Legacy-iOS-Kit为老款iPhone/iPad降级:5步拯救卡顿设备
  • 从流体力学到临床:一文搞懂FFR(血流储备分数)的计算原理与核心价值