一文理清FastAPI参数:从Query、Path到BaseModel的实战指南
刚学 FastAPI是不是总被路径参数、查询参数、请求体这些概念绕晕不知道数据从哪儿来、该怎么接事实上正确使用参数声明能让你的 API 代码量减少一半且自动获得完美的交互文档。本文带你一次搞懂 FastAPI 中的所有核心参数类型从简单的查询字符串?namevalue到定义URL片段的路径参数再到处理复杂 JSON 或表单数据的请求体。重点深入 Pydantic BaseModel教你如何用它优雅地定义、验证和组织复杂数据并自动生成 API 文档。读完你就能清晰地规划 API 的数据接口了。- ✨ 查询参数与路径参数基础与区别- 请求体参数JSON (Body) 与 表单 (Form) 处理- 混合参数路径、查询、请求体同时使用- ️ 结构化利器Pydantic BaseModel 详解与应用- 完整实战示例与代码参考✨ 查询参数与路径参数地基要打牢这是两种最基础、最常用的参数都直接体现在 URL 中。查询参数Query Parameters跟在 URL 问号?后面格式为key1value1key2value2。在 FastAPI 中函数参数不是路径的一部分的默认就是查询参数。from fastapi import FastAPI app FastAPI() app.get(/items/) async def read_items(skip: int 0, limit: int 10): # skip和limit就是查询参数如/items/?skip20limit5 return {skip: skip, limit: limit}使用skip: int 0形式就定义了带默认值的可选参数。如果没有默认值如name: str它就是必需的查询参数。路径参数Path Parameters直接是 URL 路径的一部分用花括号{}声明。通常用于唯一标识资源比如根据ID获取某篇文章。app.get(/items/{item_id}) async def read_item(item_id: int): # item_id 是路径参数 return {item_id: item_id}注意它们的顺序如果把/items/{item_id}和/items/me两个端点都定义要把具体的路径/items/me放在前面否则me会被当成item_id的值。 请求体参数处理复杂数据当你需要客户端发送较多数据如创建新文章时就需要请求体。FastAPI 用Body(),Form()等工具函数来声明。JSON 请求体Body最常见的 REST API 数据格式。使用 Pydantic 的BaseModel是最佳实践下文详解也可用Body()直接声明多个参数。from fastapi import Body app.put(/items/{item_id}) async def update_item( item_id: int, name: str Body(...), # Body(...) 表示必需项 description: str Body(None) # Body(None) 表示可选项 ): return {item_id: item_id, name: name, description: description}表单数据Form当数据来自 HTML 表单或需要上传文件时使用。如何要上传大文件需要先安装python-multipart。from fastapi import Form app.post(/login/) async def login(username: str Form(...), password: str Form(...)): return {username: username} 混合参数自由组合各司其职FastAPI 能智能地区分参数来源你可以同时使用路径、查询和请求体参数。from fastapi import Path, Query, Body app.put(/mixed-items/{item_id}) async def update_mixed_item( *, item_id: int Path(..., title商品ID, ge1), # 路径参数1 q: str Query(None, aliasquery-string), # 可选查询参数别名 item: dict Body(...) # 必需的JSON请求体 ): results {item_id: item_id} if q: results.update({q: q}) results.update({item: item}) return results这里用到了参数校验ge1表示值大于等于1。Query,Path,Body等函数让声明更明确且功能更强大如添加描述、别名、校验。️ 结构化利器Pydantic BaseModel这是 FastAPI 的灵魂特性之一。BaseModel 让你用 Python 类来定义数据模型它自动处理数据验证、序列化和文档生成。from pydantic import BaseModel, EmailStr from typing import Optional, List class UserCreate(BaseModel): # 必需字段 username: str email: EmailStr # 内置邮箱格式验证 # 可选字段带默认值 full_name: Optional[str] None # 列表类型 tags: List[str] [] app.post(/users/) async def create_user(user: UserCreate): # 一个参数接管整个请求体 # 直接访问已验证好的数据 if user.full_name: greeting fHello, {user.full_name}! else: greeting fHello, {user.username}! return {message: greeting, user_info: user.dict()}BaseModel 的优势-声明即验证字段类型不对、邮箱格式错误等会自动返回 422 错误。-自动文档Swagger UI 和 ReDoc 会自动显示模型结构和示例。-代码清晰数据契约明确业务逻辑与数据验证分离。-嵌套自由模型可以嵌套其他模型轻松处理复杂数据。 完整代码示例下面是一个融合了主要参数类型的实战示例你可以直接复制运行。from fastapi import FastAPI, Path, Query, Body from pydantic import BaseModel from typing import Optional from datetime import datetime app FastAPI(title参数详解示例) class Item(BaseModel): name: str description: Optional[str] None price: float Body(..., gt0) tax: Optional[float] None tags: list [] app.post(/advanced-items/{category}) async def create_advanced_item( category: str Path(..., description物品分类), item_id: int Query(..., ge1, description物品ID), q: Optional[str] Query(None, max_length50), urgent: bool Query(False), item: Item Body(..., example{ # 为文档提供示例 name: Foo, price: 50.5, tags: [cool, new] }) ): 创建新物品的复杂端点 total item.price (item.tax if item.tax else 0) result { category: category, item_id: item_id, query_string: q, urgent: urgent, item_name: item.name, total_price: total, created_at: datetime.now().isoformat() } return result if __name__ __main__: import uvicorn uvicorn.run(app, host0.0.0.0, port8000)运行后访问http://127.0.0.1:8000/docs你将看到一个功能齐全的交互式 API 文档所有参数和模型都清晰可见。