Python FastAPI 参数传递与响应校验

FastAPI 进阶教程:参数传递与响应校验

上一节我们实现了基础的 HelloWorld API,这一节将聚焦实际开发核心需求 ------ 参数传递(路径 / 查询 / 请求体)与响应数据校验,结合 Pydantic 模型让接口更规范、更健壮。

一、核心依赖与前置说明

  • 依赖工具:Pydantic(FastAPI 内置,用于数据校验和模型定义)。
  • 核心目标:通过类型注解定义参数 / 响应格式,FastAPI 自动完成校验、转换和文档生成。
  • 适用场景:接口需要接收用户输入(如查询条件、表单数据)或返回结构化结果时。

二、参数传递的 3 种核心方式

2.1 路径参数(Path Parameters)

用于标识资源的唯一标识(如用户 ID、商品编号),直接嵌入 URL 路径中。

基础用法(无校验)
python 复制代码
from fastapi import FastAPI
app = FastAPI()
# 路径参数 item_id 嵌入 URL,类型注解为 int
@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id, "message": "获取商品成功"}
  • 自动转换:若访问 items/abc,FastAPI 会返回 422 错误(类型不匹配),无需手动处理。
进阶用法(路径参数校验)

通过 Path 类添加校验规则(如数值范围、描述):

python 复制代码
from fastapi import FastAPI, Path
from typing import Optional
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(
    # ge=1:大于等于 1,le=100:小于等于 100,description 用于接口文档
    item_id: int = Path(..., ge=1, le=100, description="商品 ID,范围 1-100"),
    q: Optional[str] = None  # 可选查询参数,下文详解
):
    return {"item_id": item_id, "q": q}
  • 访问示例:/items/50?q=手机 正常响应,/items/101 会返回 422 校验错误。

2.2 查询参数(Query Parameters)

用于过滤、分页等非核心参数(如搜索关键词、页码),以 ?key=value 形式附加在 URL 后。

基础用法(可选参数 + 默认值)
python 复制代码
@app.get("/users/")
async def get_users(
    page: int = 1,  # 必选查询参数,默认值 1(不传递时使用默认值)
    limit: int = 10,  # 每页条数,默认 10
    keyword: Optional[str] = None  # 可选查询参数,默认 None
):
    # 模拟分页查询逻辑
    return {
        "page": page,
        "limit": limit,
        "keyword": keyword,
        "data": [{"user_id": 1, "name": "张三"}, {"user_id": 2, "name": "李四"}]
    }
  • 访问示例:/users/?page=2&limit=20&keyword=张,返回对应分页和筛选结果。
  • 校验特性:若传递 page=abc,会自动返回类型错误。
进阶用法(查询参数校验)

通过 Query 类添加校验规则(如字符串长度、正则匹配):

python 复制代码
from fastapi import FastAPI, Query
@app.get("/users/")
async def get_users(
    page: int = Query(1, ge=1, description="页码,最小 1"),
    limit: int = Query(10, ge=5, le=50, description="每页条数,5-50 条"),
    # min_length=2:最小长度 2,max_length=10:最大长度 10
    keyword: Optional[str] = Query(None, min_length=2, max_length=10)
):
    return {"page": page, "limit": limit, "keyword": keyword, "data": []}

2.3 请求体(Request Body)

用于传递复杂数据(如创建用户、提交表单),以 JSON 格式发送(FastAPI 自动解析)。

需通过 Pydantic 模型定义请求体结构。

步骤 1:定义 Pydantic 模型
python 复制代码
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
# 定义请求体模型,继承 BaseModel
class UserCreate(BaseModel):
    name: str  # 必选字段,字符串类型
    age: int = Field(..., ge=0, le=120, description="年龄,0-120 岁")  # 带校验的必选字段
    email: str = Field(..., pattern=r"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+.[a-zA-Z0-9_-]+$")  # 邮箱正则校验
    address: Optional[str] = None  # 可选字段,默认 None
# 定义响应体模型(可选,用于规范返回格式)
class UserResponse(BaseModel):
    id: int
    name: str
    age: int
    email: str
    address: Optional[str] = None
    class Config:
        orm_mode = True  # 支持从 ORM 对象(如 SQLAlchemy 模型)转换为 JSON
步骤 2:使用模型接收请求体
python 复制代码
@app.post("/users/", response_model=UserResponse)  # 指定响应模型,自动校验返回数据
async def create_user(user: UserCreate):  # user 参数自动解析 JSON 请求体
    # 模拟数据库插入,生成用户 ID
    user_id = 1001
    # 返回数据会被 UserResponse 校验,确保格式一致
    return {
        "id": user_id,
        "name": user.name,
        "age": user.age,
        "email": user.email,
        "address": user.address
    }
测试请求体
perl 复制代码
{
    "name": "王五",
    "age": 25,
    "email": "wangwu@example.com",
    "address": "北京市海淀区"
}
  • 响应结果:自动校验请求体(如 email 格式错误会返回 422),返回数据严格遵循 UserResponse 结构。

三、响应校验的核心作用

  1. 确保返回数据格式统一,避免前端对接混乱。
  1. 自动过滤多余字段(如请求体中的额外参数不会被返回)。
  1. 文档自动同步:/docs 页面会显示请求体和响应体的结构化示例。

四、实战:组合参数示例(路径 + 查询 + 请求体)

python 复制代码
@app.put("/items/{item_id}", response_model=UserResponse)
async def update_item(
    item_id: int = Path(..., ge=1, description="商品 ID"),
    is_active: bool = Query(True, description="是否启用商品"),
    user: UserCreate  # 请求体
):
    return {
        "id": item_id,
        "name": user.name,
        "age": user.age,
        "email": user.email,
        "address": user.address
    }
  • 校验逻辑:路径参数、查询参数、请求体分别按规则校验,任意环节出错返回 422 错误。

五、常见错误与排查

  • 422 错误:数据校验失败(如类型不匹配、数值超出范围、正则不匹配),查看响应体的 detail 字段可获取具体原因。
  • 请求体无法解析:未定义 Pydantic 模型,或请求头 Content-Type 不是 application/json。
  • 可选字段必填:未给 Optional 字段设置默认值(如 keyword: Optional[str] 需改为 keyword: Optional[str] = None)。
相关推荐
NiShiKiFuNa2 小时前
AutoHotkey 功能配置与使用指南
后端
黎燃2 小时前
基于生产负载回放的数据库迁移验证实践:从模拟测试到真实预演【金仓数据库】
后端
文心快码BaiduComate2 小时前
双十一将至,用Rules玩转电商场景提效
前端·人工智能·后端
该用户已不存在2 小时前
免费的 Vibe Coding 助手?你想要的Gemini CLI 都有
人工智能·后端·ai编程
bcbnb3 小时前
uni-app iOS性能监控全攻略,跨端架构下的性能采集、分析与多工具协同优化实战
后端
qq_12498707533 小时前
基于springboot+vue的物流管理系统的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·毕业设计
CryptoRzz3 小时前
DeepSeek印度股票数据源 Java 对接文档
前端·后端
刘一说4 小时前
深入理解 Spring Boot Actuator:构建可观测性与运维友好的应用
运维·spring boot·后端
oak隔壁找我4 小时前
Spring AI 入门教程,使用Ollama本地模型集成,实现对话记忆功能。
java·人工智能·后端