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

FastAPI 请求详解:全面掌握各种请求类型处理

FastAPI 是一个现代、快速(高性能)的 Python Web 框架,基于标准的 Python 类型提示构建,支持异步处理,内置自动生成 API 文档(Swagger UI 和 ReDoc),并以极简语法实现强大的请求处理能力。本文将系统性地介绍 FastAPI 如何处理各种类型的 HTTP 请求,涵盖路径参数、查询参数、请求体、文件上传、表单数据、Header/Cookie 等核心功能,并结合 Pydantic 验证、异常处理和最佳实践,帮助你构建健壮、可维护的 RESTful API。
📅 FastAPI 版本兼容性:本文基于 fastapi>=0.95 编写,适用于当前主流版本


一、HTTP 方法(HTTP Verbs)与路由设计

在 RESTful 架构中,不同的 HTTP 方法对应不同的资源操作语义。FastAPI 使用装饰器绑定路由与处理函数,简洁直观。

from fastapi import FastAPIapp = FastAPI()@app.get("/items")           # 获取资源列表
async def read_items():return {"message": "获取所有 items"}@app.post("/items")          # 创建新资源
async def create_item():return {"message": "创建 item"}@app.put("/items/{id}")      # 全量更新资源(幂等)
async def update_item(id: int):return {"message": f"全量更新 item {id}"}@app.patch("/items/{id}")    # 部分更新资源
async def partial_update_item(id: int):return {"message": f"部分更新 item {id}"}@app.delete("/items/{id}")   # 删除资源(幂等)
async def delete_item(id: int):return {"message": f"删除 item {id}"}@app.options("/items")       # 获取服务器支持的操作方法
async def options_items():return {"allow": "GET, POST, PUT, DELETE, OPTIONS"}@app.head("/items")          # 获取响应头(无响应体)
async def head_items():return {}@app.trace("/items")         # 回显请求(调试用途)
async def trace_items():return {"message": "TRACE 请求已收到"}

✅ RESTful 设计原则回顾

方法

幂等性

安全性

用途说明

GET

✅ 幂等

✅ 安全

获取资源,不应产生副作用

POST

❌ 非幂等

❌ 不安全

创建资源,每次调用可能生成新资源

PUT

✅ 幂等

❌ 不安全

全量替换资源,不存在则创建

PATCH

❌ 非幂等

❌ 不安全

局部更新资源

DELETE

✅ 幂等

❌ 不安全

删除资源,多次调用结果一致

💡 提示:尽量遵循 REST 语义,避免滥用 POST 承担所有操作。


二、路径参数(Path Parameters)——动态路由

路径参数用于捕获 URL 中的动态部分,如用户 ID、商品编号等。

1. 基础用法 + 类型验证

@app.get("/users/{user_id}")
def get_user(user_id: int):return {"user_id": user_id, "type": type(user_id).__name__}
  • 访问 /users/123 → 返回 {"user_id": 123, "type": "int"}
  • 访问 /users/abc → 自动返回 422 Unprocessable Entity 错误(类型不匹配)

FastAPI 借助 Pydantic 实现了自动类型转换与验证。支持的类型包括:

  • int, float, bool, str
  • datetime, date, time
  • UUID, Path, List, Dict

2. 多级路径参数

@app.get("/users/{user_id}/orders/{order_id}")
def get_user_order(user_id: int, order_id: str):return {"user_id": user_id, "order_id": order_id}

URL 示例:/users/42/orders/ORD-1001

3. 包含斜杠的路径(通配符路径)

使用 path() 类型表示可包含 / 的路径段:

from fastapi import Path@app.get("/files/{file_path:path}")
def read_file(file_path: str):return {"file_path": file_path}

示例:

  • /files/path/to/file.txtfile_path = "path/to/file.txt"
  • /files/config.jsonfile_path = "config.json"

⚠️ 注意:{file_path:path} 必须是最后一个路径段,否则会捕获后续路径。


三、查询参数(Query Parameters)——灵活过滤与分页

查询参数是 URL ? 后的部分,用于传递可选参数,如分页、搜索关键词等。

1. 基本查询参数(带默认值)

python
@app.get("/items")
def read_items(skip: int = 0, limit: int = 10, q: str = None):params = {"skip": skip, "limit": limit}if q:params["q"] = qreturn params

请求示例:

GET /items?q=phone&skip=5&limit=20
→ 返回 {"skip": 5, "limit": 20, "q": "phone"}
  • 有默认值 → 可选参数
  • 无默认值 → 必填参数(会自动校验)

2. 显式定义查询参数(使用 Query

Query 提供更丰富的验证和文档控制:

from fastapi import Query@app.get("/items/required")
def required_query(q: str = Query(..., min_length=3, description="搜索关键词")):return {"q": q}
  • ... 表示必填
  • min_length=3:最小长度
  • description:出现在 Swagger 文档中

3. 多值查询参数(List)

@app.get("/items/tags")
def filter_by_tags(tags: list[str] = Query(["electronics", "mobile"])) -> dict:return {"tags": tags}

请求示例:

GET /items/tags?tags=phone&tags=apple
→ tags = ["phone", "apple"]

4. 查询参数约束(高级验证)

@app.get("/items/search")
def search_items(q: str = Query(..., min_length=2, max_length=50, regex="^[a-zA-Z0-9_\\s]+$"),page: int = Query(1, gt=0, le=1000),size: int = Query(10, ge=1, le=100),sort: str = Query("created_at", enum=["name", "price", "created_at"])
):return {"q": q, "page": page, "size": size, "sort": sort}
  • regex:正则表达式校验
  • enum:限制可选值
  • gt, ge, lt, le:数值范围

最佳实践:为查询参数添加合理的默认值和边界限制,防止恶意请求耗尽资源。


四、请求体(Request Body)——接收复杂数据

使用 Pydantic 模型定义 JSON 请求体结构,实现自动解析、类型转换和验证。

1. 定义 Pydantic 模型

from pydantic import BaseModel
from typing import Optionalclass Item(BaseModel):name: strdescription: Optional[str] = Noneprice: floattax: Optional[float] = None = None

2. 接收请求体

@app.post("/items")
def create_item(item: Item):total_price = item.price + (item.tax or 0)return {"item": item.dict(),"total_price": total_price}

请求示例(JSON):

{"name": "MacBook Pro","description": "Apple M1 Pro, 16GB RAM","price": 1999.99,"tax": 199.99
}

3. 多个请求体参数(使用 Body

当需要接收多个 JSON 字段时,使用 embed=True 包装:

from fastapi import Body@app.post("/items/{item_id}")
def update_item(item_id: int,item: Item = Body(..., embed=True),importance: int = Body(..., gt=0, embed=True)
):return {"item_id": item_id, "item": item, "importance": importance}

请求体示例:

{"item": {"name": "Laptop","price": 1200},"importance": 5
}

4. 混合参数(路径 + 查询 + 请求体)

@app.put("/items/{item_id}")
def complex_update(item_id: int,q: str = None,item: Item = Body(...)
):result = {"item_id": item_id}if q:result["q"] = qresult["item"] = itemreturn result

⚠️ 注意顺序:路径参数 → 查询参数 → 请求体参数(顺序不影响功能,但建议保持一致)


五、Header 与 Cookie 参数

用于获取客户端元信息或会话标识。

1. 读取 Cookie

from fastapi import Cookie@app.get("/profile")
def get_profile(session_id: str = Cookie(None)):if not session_id:return {"error": "未登录"}return {"session_id": session_id}

2. 读取 Header

from fastapi import Header@app.get("/info")
def get_client_info(user_agent: str = Header(...),x_token: list[str] = Header(None),  # 支持重复 Headeraccept_language: str = Header("zh-CN")
):return {"user_agent": user_agent,"x_token": x_token,"language": accept_language}

常见用途

  • User-Agent:识别客户端设备
  • Authorization:JWT 认证(通常用 Depends 提取)
  • X-Request-ID:链路追踪
  • Accept-Language:国际化支持

六、文件上传(File Upload)

使用 UploadFile 类处理 multipart/form-data 请求。

1. 单文件上传

from fastapi import File, UploadFile@app.post("/upload/")
async def upload_file(file: UploadFile = File(...)):contents = await file.read()return {"filename": file.filename,"content_type": file.content_type,"size": len(contents),"encoding": file.headers.get("content-transfer-encoding")}

2. 多文件上传

@app.post("/upload/multiple/")
async def upload_multiple(files: list[UploadFile] = File(...)):results = []for file in files:content = await file.read()results.append({"filename": file.filename,"size": len(content),"content_type": file.content_type})return results

📌 前端示例(HTML)

<form action="/upload/multiple/" method="post" enctype="multipart/form-data"><input type="file" name="files" multiple><button type="submit">上传</button>
</form>

⚠️ 安全建议

  • 限制文件大小(使用 max_length
  • 校验文件类型(MIME 类型 + 文件头)
  • 存储路径避免用户可控
  • 异步写入磁盘(避免阻塞)

七、表单数据(Form Data)

处理 application/x-www-form-urlencoded 格式的表单提交。

from fastapi import Form@app.post("/login/")
def login(username: str = Form(...), password: str = Form(...)):# 实际项目中应使用 OAuth2 或 JWTreturn {"username": username}

🔍 注意:不能同时使用 FormBody 接收 JSON,FastAPI 会根据 Content-Type 自动选择解析方式。


八、原始请求对象(Request)——深入底层

获取完整的请求上下文信息:

from fastapi import Request@app.get("/debug")
async def debug_request(request: Request):return {"url": str(request.url),"method": request.method,"headers": dict(request.headers),"query_params": dict(request.query_params),"path_params": request.path_params,"client": request.client,"cookies": request.cookies,"body": await request.body()  # 注意:只能读取一次}

⚠️ 警告await request.body() 会消耗流,后续中间件或函数无法再次读取。


九、请求验证失败处理(422 Error)

当请求数据不符合模型定义时,FastAPI 自动返回 422 Unprocessable Entity

你可以自定义错误响应格式:

from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):return JSONResponse(status_code=422,content={"code": 422,"message": "数据验证失败,请检查输入","details": [{"field": ".".join(str(loc) for loc in error["loc"]),"message": error["msg"],"type": error["type"],"input": error.get("input", None)}for error in exc.errors()]})

生产建议:将此异常处理器封装为通用模块,统一 API 错误格式。


十、最佳实践与常见陷阱

实践

说明

✅ 使用 Pydantic 模型

提高类型安全,自动生成文档,便于复用

✅ 合理设置默认值

区分必填与可选参数,提升 API 友好性

✅ 添加参数约束

使用 Query, Path, Body添加验证规则

✅ 保持路由简洁

避免在一个接口中混合过多参数类型

✅ 利用自动文档

/docs/redoc 可用于测试和分享 API

✅ 统一错误处理

自定义异常处理器,返回结构化错误信息

✅ 异步处理 I/O

文件读写、数据库操作使用 async/await

❌ 避免在请求体中传递 ID

ID 应通过路径参数传递,符合 REST 规范


十一、总结

FastAPI 提供了一套声明式、类型安全、高度自动化的请求处理机制,极大提升了开发效率与 API 质量。以下是核心请求处理方式的总结:

请求部分

处理方式

路径参数

{param}+ 类型注解

查询参数

函数参数 + Query()

请求体

Pydantic 模型 + Body()

Header

Header()

Cookie

Cookie()

文件上传

UploadFile+ File()

表单数据

Form()

原始请求

Request对象

通过合理组合这些机制,你可以构建出功能强大、结构清晰、易于维护的现代 Web API。

http://www.lryc.cn/news/625918.html

相关文章:

  • 《基于大数据的全球用水量数据可视化分析系统》用Python+Django开发,为什么导师却推荐用Java+Spring Boot?真相揭秘……
  • 实践项目-1
  • Matplotlib数据可视化实战:Matplotlib图表注释与美化入门
  • LeetCode100-560和为K的子数组
  • Rust学习笔记(七)|错误处理
  • 2025年渗透测试面试题总结-21(题目+回答)
  • 堆、方法区、虚拟机栈、本地方法栈、程序计数器
  • RabbitMQ:SpringAMQP 多消费者绑定同一队列
  • Java配置文件
  • 第1章 React组件开发基础
  • 第10章 React应用测试
  • 我的SSM框架自学2
  • IDEA测试代码报java file outset source root异常
  • STM32-FreeRTOS快速入门指南(中)
  • 【软件安装】VScode介绍安装步骤及中文界面设置方法
  • 从数据孤岛到实时互联:Canal 驱动的系统间数据同步实战指南
  • Java 11中的Collections类详解
  • 正式签约 | OpenLoong 项目正式捐赠至开放原子开源基金会,成为全国首个具身智能方向孵化项目!
  • Vulkan笔记(十三)-帧缓冲区与命令池命令缓冲区
  • 使用 SemanticKernel 连接本地大模型 Ollama
  • 11.Ansible自动化之-内容集管理
  • 快手Klear-Reasoner登顶8B模型榜首,GPPO算法双效强化稳定性与探索能力!
  • 图像增强——灰度变换增强(线性,对数,指数)、空间滤波增强、频域增强、主成分/彩色合成增强(原理解释和代码示例)
  • FPGA 在情绪识别领域的护理应用(一)
  • Spring Boot应用实现图片资源服务
  • 电商数据分析可视化预测系统
  • gitlab、jenkins等应用集成ldap
  • Wireshark获取数据传输的码元速率
  • 【iOS】内存管理
  • implement libtime on Windows