文章目录
-
- 前言
- 一、阶段学习目标
- [二、核心概念:查询参数 vs 请求体](#二、核心概念:查询参数 vs 请求体)
-
- [2\.1 核心区别(新手必记)](#2.1 核心区别(新手必记))
- [2\.2 FastAPI识别规则](#2.2 FastAPI识别规则)
- 三、核心实战:Pydantic请求体
-
- [3\.1 基础请求体(单层级)](#3.1 基础请求体(单层级))
- [3\.2 运行测试](#3.2 运行测试)
- [3\.3 嵌套请求体(复杂业务必备)](#3.3 嵌套请求体(复杂业务必备))
- 四、核心重点:响应模型与数据脱敏(生产必备)
-
- [4\.1 入参、出参模型分层(生产规范)](#4.1 入参、出参模型分层(生产规范))
- [4\.2 响应模型实战脱敏](#4.2 响应模型实战脱敏)
- [4\.3 响应模型进阶配置](#4.3 响应模型进阶配置)
-
- [4\.3\.1 exclude\_unset:只返回赋值字段](#4.3.1 exclude_unset:只返回赋值字段)
- [4\.3\.2 手动指定排除/包含字段](#4.3.2 手动指定排除/包含字段)
- 五、混合传参:三种参数同时使用
- [六、Header 与 Cookie 参数获取](#六、Header 与 Cookie 参数获取)
- 七、生产级统一响应体封装
- 八、阶段综合实战:完整用户CRUD(脱敏\+统一返回)
- 九、新手高频避坑指南
- 十、阶段核心总结
前言
上一阶段我们掌握了FastAPI基础接口、路径参数、查询参数、RESTful规范与自动文档,能快速编写基础查询接口。但真实业务中,新增、修改、编辑数据几乎都需要传递复杂JSON数据,单纯的查询参数完全无法满足需求。
这就需要用到FastAPI核心核心能力:请求体 + 响应模型。
本阶段最大优势:100%复用你已精通的Pydantic知识。FastAPI的请求校验、数据序列化、字段约束、脱敏返回,全部基于Pydantic v2实现,无需学习新语法,无缝衔接旧知识。
本文耗时1天学完,彻底解决业务核心问题:
-
复杂JSON请求参数接收、自动校验、类型转换;
-
接口返回数据脱敏、字段过滤、统一格式化;
-
路径参数、查询参数、请求体混合传参;
-
Header、Cookie请求头参数获取;
-
生产级DTO分层(入参模型/出参模型分离)。
一、阶段学习目标
-
彻底分清查询参数 与请求体的使用场景与区别;
-
熟练使用Pydantic BaseModel定义POST/PUT请求体,掌握字段校验、默认值、必填规则;
-
掌握嵌套请求体模型,适配复杂多层JSON参数场景;
-
精通response_model响应模型,实现密码脱敏、字段过滤、数据格式化;
-
掌握三种参数混合使用:路径参数 + 查询参数 + 请求体;
-
学会获取Header请求头、Cookie参数;
-
搭建生产级统一接口返回体,实现前后端格式统一;
-
完成用户新增、编辑、脱敏查询完整实战接口。
二、核心概念:查询参数 vs 请求体
2.1 核心区别(新手必记)
上一阶段的路径参数、查询参数,仅适用于简单少量参数、查询场景 ;而请求体专门用于复杂JSON、大批量数据、新增/修改场景。
| 参数类型 | 传输位置 | 适用请求方法 | 数据格式 | 业务场景 |
|---|---|---|---|---|
| 查询参数 | URL ? 后拼接 | GET 为主 | 简单键值对 | 分页、筛选、搜索、ID查询 |
| 请求体 | HTTP 请求体 | POST/PUT/PATCH | 复杂JSON、嵌套结构 | 新增数据、编辑数据、批量提交 |
2.2 FastAPI识别规则
这是FastAPI的核心智能规则,无需手动声明:
-
普通基础类型(int/str/bool)= 自动识别为查询参数;
-
Pydantic模型类型(继承BaseModel)= 自动识别为请求体。
三、核心实战:Pydantic请求体
所有请求体基于 Pydantic BaseModel 定义,你之前学的所有校验规则(长度、正则、邮箱、数值范围)全部通用。
3.1 基础请求体(单层级)
实现用户新增接口,接收JSON请求体,自动完成参数校验。
python
from fastapi import FastAPI, status
from pydantic import BaseModel, EmailStr, field_validator
app = FastAPI(title="请求体与响应模型实战")
# 定义请求体模型:用户新增入参
class UserCreate(BaseModel):
# 必填字段
username: str
email: EmailStr
password: str
# 可选字段,带默认值
age: int | None = None
is_active: bool = True
# 自定义字段校验(复用Pydantic能力)
@field_validator("username")
def check_username(cls, v):
if len(v) < 3:
raise ValueError("用户名长度不能小于3位")
return v
@field_validator("password")
def check_password(cls, v):
if len(v) < 6:
raise ValueError("密码长度不能小于6位")
return v
# POST接口:接收JSON请求体
@app.post("/users", summary="新增用户", status_code=status.HTTP_201_CREATED)
def create_user(user: UserCreate):
# 自动校验参数,非法参数直接返回422错误
# 直接返回请求数据(后续改造为脱敏响应模型)
return user
3.2 运行测试
启动项目:uvicorn main:app --reload,访问 http://127.0.0.1:8000/docs 调试:
正确请求体示例:
json
{
"username": "zhangsan",
"email": "zhangsan@qq.com",
"password": "123456",
"age": 22
}
非法场景自动拦截:邮箱格式错误、用户名过短、密码位数不足,无需手写if判断。

3.3 嵌套请求体(复杂业务必备)
真实业务常出现多层嵌套JSON(如用户绑定收货地址),FastAPI+Pydantic完美支持嵌套模型。
python
# 嵌套子模型:收货地址
class Address(BaseModel):
province: str
city: str
detail: str
# 父模型:用户新增(嵌套地址)
class UserCreateWithAddr(BaseModel):
username: str
email: EmailStr
password: str
address: Address # 嵌套子模型
age: int | None = None
# 嵌套请求体接口
@app.post("/users/addr", summary="新增用户+绑定地址")
def create_user_with_addr(user: UserCreateWithAddr):
return user
请求体支持多层嵌套,自动递归校验所有字段,适配复杂业务参数。
四、核心重点:响应模型与数据脱敏(生产必备)
最大生产坑点:直接返回数据库/请求原始数据,会泄露密码、密钥等敏感信息。
解决方案:使用 response_model 响应模型,实现字段过滤、敏感数据脱敏、返回格式统一。
4.1 入参、出参模型分层(生产规范)
严格分层,禁止同一模型既做入参又做出参:
-
UserCreate:新增入参模型(包含密码)
-
UserPublic:返回出参模型(剔除密码、脱敏字段)
4.2 响应模型实战脱敏
python
# 响应模型:用户公开信息(脱敏)
class UserPublic(BaseModel):
id: int
username: str
email: EmailStr
age: int | None = None
is_active: bool
# 关键配置:支持ORM/字典对象自动转换
class Config:
from_attributes = True
# 模拟数据库
fake_user_db = []
# 改造新增接口,添加响应模型脱敏
@app.post("/users", summary="新增用户(脱敏返回)", response_model=UserPublic, status_code=status.HTTP_201_CREATED)
def create_user(user: UserCreate):
# 模拟生成用户ID、存入数据库
new_user = user.model_dump()
new_user["id"] = len(fake_user_db) + 1
fake_user_db.append(new_user)
# 返回完整数据,响应模型自动剔除password字段
return new_user
核心效果 :前端传入密码,后端存储后,返回数据自动剔除password字段,彻底杜绝敏感信息泄露。
4.3 响应模型进阶配置
4.3.1 exclude_unset:只返回赋值字段
适用于局部更新场景,不返回默认空字段:
python
@app.post("/users", response_model=UserPublic, response_model_exclude_unset=True)
4.3.2 手动指定排除/包含字段
python
# 仅返回指定字段
@app.get("/users/{user_id}", response_model=UserPublic, response_model_include={"id", "username", "email"})
# 排除指定敏感字段
@app.get("/users/{user_id}", response_model_exclude={"password"})
五、混合传参:三种参数同时使用
真实业务高频场景:路径参数 + 查询参数 + 请求体 混合传参,FastAPI可智能区分、互不冲突。
场景:根据用户ID(路径参数),分页(查询参数)更新用户信息(请求体)
python
# 用户更新入参模型
class UserUpdate(BaseModel):
username: str | None = None
email: EmailStr | None = None
age: int | None = None
# 混合传参接口
@app.put("/users/{user_id}", summary="更新用户信息(混合传参)", response_model=UserPublic)
def update_user(
# 1. 路径参数:用户ID
user_id: int,
# 2. 查询参数:分页/附加筛选
is_validate: bool = True,
# 3. 请求体:更新数据JSON
user: UserUpdate
):
return {
"user_id": user_id,
"is_validate": is_validate,
**user.model_dump(exclude_unset=True)
}
FastAPI自动识别三类参数,无需手动区分,极大简化开发。
六、Header 与 Cookie 参数获取
业务常用:获取请求头Token、设备信息、Cookie会话ID,FastAPI原生支持。
python
from fastapi import Header, Cookie
@app.get("/headers", summary="获取请求头参数")
def get_headers(
# 获取自定义请求头
token: str | None = Header(default=None),
# 获取浏览器UA
user_agent: str | None = Header(default=None),
# 获取Cookie
session_id: str | None = Cookie(default=None)
):
return {
"token": token,
"user_agent": user_agent,
"session_id": session_id
}
常用场景:接口鉴权获取Token、统计客户端设备、会话状态校验。
七、生产级统一响应体封装
原生返回格式杂乱,前端对接繁琐,我们封装泛型统一返回体,适配所有接口,前后端统一规范。
python
from typing import Generic, TypeVar, Optional
# 泛型定义
T = TypeVar("T")
# 统一响应模型
class ApiResp(BaseModel, Generic[T]):
code: int = 200
msg: str = "请求成功"
data: Optional[T] = None
# 快捷工具函数
def success_resp(data: T | None = None, msg: str = "请求成功") -> ApiResp[T]:
return ApiResp(data=data, msg=msg)
def fail_resp(msg: str = "请求失败", code: int = 400) -> ApiResp:
return ApiResp(code=code, msg=msg)
# 改造接口,使用统一返回体
@app.get("/users/{user_id}", summary="查询用户详情", response_model=ApiResp[UserPublic])
def get_user(user_id: int):
if user_id > len(fake_user_db):
return fail_resp(msg="用户不存在", code=404)
return success_resp(data=fake_user_db[user_id-1])
统一返回格式:{code, msg, data},前端无需适配多种返回结构,生产项目必备。
八、阶段综合实战:完整用户CRUD(脱敏+统一返回)
整合本阶段所有知识点,实现可直接上线的用户新增、查询、更新接口,包含:参数校验、嵌套模型、数据脱敏、统一响应、混合传参。
python
from fastapi import FastAPI, Header, Cookie, status
from pydantic import BaseModel, EmailStr, field_validator
from typing import Generic, TypeVar, Optional
# ====================== 1. 统一响应封装 ======================
T = TypeVar("T")
class ApiResp(BaseModel, Generic[T]):
code: int = 200
msg: str = "请求成功"
data: Optional[T] = None
def success_resp(data=None, msg="请求成功"):
return ApiResp(data=data, msg=msg)
def fail_resp(msg="请求失败", code=400):
return ApiResp(code=code, msg=msg)
# ====================== 2. 模型分层(入参/出参) ======================
class UserCreate(BaseModel):
username: str
email: EmailStr
password: str
age: int | None = None
@field_validator("username")
def check_username(cls, v):
if len(v) < 3:
raise ValueError("用户名至少3位")
return v
class UserUpdate(BaseModel):
username: str | None = None
email: EmailStr | None = None
age: int | None = None
class UserPublic(BaseModel):
id: int
username: str
email: EmailStr
age: int | None = None
class Config:
from_attributes = True
# ====================== 3. 项目初始化 ======================
app = FastAPI(title="第二阶段综合实战")
fake_db = []
# ====================== 4. 业务接口 ======================
@app.post("/users", summary="新增用户", response_model=ApiResp[UserPublic], status_code=status.HTTP_201_CREATED)
def create_user(user: UserCreate):
"""新增用户,自动脱敏返回"""
new_user = user.model_dump()
new_user["id"] = len(fake_db) + 1
fake_db.append(new_user)
return success_resp(data=new_user)
@app.get("/users/{user_id}", summary="查询用户", response_model=ApiResp[UserPublic])
def get_user(user_id: int):
"""根据ID查询脱敏用户信息"""
if user_id < 1 or user_id > len(fake_db):
return fail_resp("用户不存在", 404)
return success_resp(data=fake_db[user_id-1])
@app.put("/users/{user_id}", summary="更新用户", response_model=ApiResp[UserPublic])
def update_user(user_id: int, user: UserUpdate):
"""局部更新用户信息"""
if user_id < 1 or user_id > len(fake_db):
return fail_resp("用户不存在", 404)
update_data = user.model_dump(exclude_unset=True)
fake_db[user_id-1].update(update_data)
return success_resp(data=fake_db[user_id-1])
九、新手高频避坑指南
-
❌ GET接口使用请求体:HTTP规范禁止GET携带请求体,查询参数只用查询参数;
-
❌ 入参出参共用一个模型:必然导致密码、密钥泄露,必须分层DTO;
-
❌ 忽略from_attributes配置:ORM对象无法转换为响应模型,直接报错;
-
❌ 不做数据脱敏直接返回原始数据:生产重大安全漏洞;
-
❌ 混合传参参数名冲突:路径参数、查询参数、请求体参数建议命名区分;
-
✅ 严格分层模型:Create/Update/Public三类模型各司其职;
-
✅ 所有生产接口统一响应体,杜绝返回格式混乱;
-
✅ 复杂参数一律用请求体,简单筛选用查询参数。
十、阶段核心总结
-
参数区分:基础类型=查询参数,Pydantic模型=请求体,GET无请求体、POST/PUT核心用请求体;
-
请求体核心:完全复用Pydantic校验能力,支持单层/嵌套复杂JSON,自动参数校验;
-
响应模型核心:response_model实现字段过滤、敏感数据脱敏、返回格式标准化,生产必备;
-
混合传参:FastAPI支持路径+查询+请求体+Header+Cookie多参数共存,智能解析;
-
工程规范:入参出参模型分层、统一泛型响应体,贴合企业后端开发标准。