新手必看:FastAPI 参数接收的正确姿势(路径 / 查询 / 请求体全解析)
本篇详细讲解 FastAPI 接口开发中最核心的三种参数接收方式:路径参数、查询参数、请求体,从概念、实操代码到可视化测试一步步拆解。同时加入 Path、Query、Field 参数校验与文档美化,让新手快速掌握前端传参、后端接收的完整逻辑,轻松写出规范、可上线的接口。
继上一篇《FastAPI 零基础入门:从安装到快速搭建 Web 接口》之后,本篇聚焦 FastAPI 最核心的参数接收能力 —— 路径参数、查询参数、请求体,用(大白话 + 实操代码 + 可视化测试)的方式拆解,新手跟着敲代码就能懂,掌握后就能实现真正的 “数据交互型接口”。
前言
上一篇我们学会了搭建基础接口和四种请求方法,但实际开发中,接口不可能只返回固定数据:比如根据用户 ID 查信息、分页查询列表、提交用户注册信息… 这些都需要前端给后端传数据,而 FastAPI 接收前端数据的核心方式就是路径参数、查询参数、请求体,这也是新手从 “写死数据” 到 “动态交互” 的关键一步。
前置准备
确保你已经完成:
- 安装 FastAPI 和 uvicorn(pip install fastapi uvicorn);
- 熟悉基础的 FastAPI 项目结构和启动方式;
- 保留上一篇的 main.py 文件,本篇代码都基于这个文件迭代。
1 路径参数:从URL路径中取数据
1.1.什么是路径参数?
简单来说:把参数直接写在接口URL的路径里,比如想根据用户ID查询信息,接口地址设计成 /user/1 (1就是用户ID),这个1就是路径参数。
核心场景:查询 / 操作;指定唯一资源(如用户 ID、商品 ID、文章 ID)。
1.2.基础实操:获取单个用户ID
打开main.py,编写如下代码:
from fastapi import FastAPI
import uvicorn
app = FastAPI()
# 路径参数核心语法:@app.get("/路径/{参数名}")
@app.get("/user/{user_id}", summary="根据用户ID查询用户信息")
def get_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
返回结果如下:
新手必看知识点:
- 类型注解的作用:如果访问http://127.0.0.1:8000/user/abc(传字符串),FastAPI 会自动返回 422 错误,无需手动写校验代码;
- 参数名要一致:装饰器里的{user_id}必须和函数参数user_id同名;
- 支持多种类型:除了 int,还支持 str、float、bool 等,比如/article/{article_title:str}。
2 查询参数:URL中?后面的键值对
2.1.什么是查询参数?
简单说:在 URL 末尾用?参数名=值的形式传参,多个参数用&分隔,比如/goods?page=1&size=10(page 是页码,size 是每页条数)。
核心场景:筛选、分页、模糊查询;(如列表分页、多条件筛选商品)
2.2. 基础实操:商品列表分页查询
代码如下:
from fastapi import FastAPI
import uvicorn
app = FastAPI()
# 查询参数:无需在路径中写,函数直接接收参数即可
@app.get("/goods", summary="商品列表分页查询")
def get_goods_list(
page: int = 1, # 默认值:如果前端不传,默认查第1页
size: int = 10 # 默认值:如果前端不传,默认每页10条
):
# 模拟分页数据(实际开发中根据page和size查数据库)
goods = []
for i in range(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 条数据;
返回结果:如图
新手必看知识点:
- 查询参数无需在路径中定义:函数参数直接写,FastAPI 会自动从 URL 的?后解析;
- 默认值的作用:前端不传参时使用默认值,避免报错;
- 混合使用:路径参数和查询参数可以一起用,比如/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 中新增如下代码:
from fastapi import FastAPI
import uvicorn
from pydantic import BaseModel # 导入Pydantic模型
app = FastAPI()
# 定义请求体模型:用户注册数据格式
class UserRegister(BaseModel):
username: str # 必填项:用户名(字符串)
password: str # 必填项:密码(字符串)
age: int = 18 # 可选项:年龄,默认18
email: str # 可选项:邮箱,可传None
# POST请求+请求体:用户注册
@app.post("/user/register", summary="用户注册")
def user_register(user_info: UserRegister): # 接收请求体,类型为自定义的UserRegister
# 模拟注册逻辑(实际开发中可写入数据库)
return {
"code": 200,
"msg": "注册成功",
"data": {
"username": user_info.username,
"age": user_info.age,
"email": user_info.email if user_info.email else "未填写"
}
}
if __name__ == '__main__':
uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)
3.3.测试请求体
请求体无法直接在浏览器访问,推荐用 FastAPI 自带的交互式文档测试:
- 启动服务后,访问http://127.0.0.1:8000/docs(自动生成的 Swagger 文档);
- 找到/user/register接口,点击「Try it out」;
- 编辑请求体 JSON(按模型格式填),示例:

- 点击 Execute,就能看到返回结果:

新手必看知识点:
- Pydantic 模型的作用:
- 自动校验:比如 age 传字符串会报错,username 不传会提示必填;
- 自动解析:把前端传的 JSON 自动转成 Python 对象,直接用user_info.username取值;
- 可选项定义:age: int = 18(默认值)、email: str | None = None(可传 None);
- 请求体只支持 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 新手避坑指南
- 参数名大小写敏感:路径参数{user_id}和函数参数user_id必须完全一致;
- 类型注解别漏写:FastAPI 靠类型注解做自动校验,漏写会失去校验能力;
- GET 请求别用请求体:前端用 GET 传请求体,后端收不到,这是 HTTP 协议规定;
- 测试工具选对:路径参数 / 查询参数用浏览器,请求体用/docs或 Postman。
6 进阶美化!Path/Query/Field 让参数更规范
这是最简单、最实用的进阶用法,不用改逻辑,只需要加一行代码,就能让你的接口:
- 带中文注释
- 加参数校验(比如数字必须大于 0)
- 接口文档更清晰
- 一看就懂每个参数干嘛用
先安装/导入(必须做)
from fastapi import FastAPI, Path, Query # 路径+查询参数专用
from pydantic import BaseModel, Field # 请求体专用
6.1.路径参数+Path
作用:给路径参数加说明、限制范围
@app.get("/user/{user_id}")
def get_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")
def get_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
作用:给请求体字段加说明、长度 / 格式校验
class UserRegister(BaseModel):
username: str = Field(..., description="用户名,必填")
password: str = Field(..., description="密码,至少6位", min_length=6)
age: int = Field(18, description="年龄,默认18")
@app.post("/user/register")
def register(user: UserRegister):
return user
min_length=6 密码最少 6 位;自动校验,不合格直接报错
三者一起用(最常用实战写法)
@app.get("/user/{user_id}/order")
def get_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 测试验证,就能完全掌握“前端传参、后端接收”的核心逻辑。下一篇我们将继续讲解响应模型、统一异常处理、依赖注入等实战内容,帮你写出生产级标准接口。
更多推荐
所有评论(0)