
【个人主页:玄同765】
大语言模型(LLM)开发工程师|中国传媒大学·数字媒体技术(智能交互与游戏设计)
深耕领域:大语言模型开发 / RAG知识库 / AI Agent落地 / 模型微调
技术栈:Python / LangChain/RAG(Dify+Redis+Milvus)| SQL/NumPy | FastAPI+Docker ️
工程能力:专注模型工程化部署、知识库构建与优化,擅长全流程解决方案
专栏传送门:LLM大模型开发 项目实战指南、Python 从真零基础到纯文本 LLM 全栈实战、从零学 SQL + 大模型应用落地、大模型开发小白专属:从 0 入门 Linux&Shell
「让AI交互更智能,让技术落地更高效」
欢迎技术探讨/项目合作! 关注我,解锁大模型与智能交互的无限可能!
你是不是搞不清 FastAPI 里 GET/POST/PUT/DELETE 的区别?或者在处理路径参数、查询参数、JSON 请求体、表单数据时犯迷糊?这篇用大量代码示例和对比表格,详解这四种核心 HTTP 请求方法的使用场景和实现步骤,让你 30 分钟内成为 FastAPI 请求处理专家。
一、引言:HTTP 请求方法是什么,为什么要区分?
在 Web 开发中,HTTP(超文本传输协议)是客户端(如浏览器、手机 APP)与服务器(如 FastAPI 应用)之间通信的标准协议。HTTP 请求方法定义了客户端对服务器资源的操作类型,常见的有四种核心方法:
- GET:请求获取服务器上的资源(如查询用户信息、获取商品列表);
- POST:向服务器提交新的资源(如用户注册、发布文章);
- PUT:更新服务器上的资源(如修改用户信息、更新文章内容);
- DELETE:删除服务器上的资源(如删除用户账号、删除评论)。
区分 HTTP 请求方法的意义在于:
- 语义明确:让服务器和客户端都能清楚地知道请求的意图;
- 缓存优化:GET 请求的响应通常可以被浏览器或 CDN 缓存,提高访问速度;
- 安全策略:POST、PUT、DELETE 请求通常需要身份验证和权限控制,防止资源被恶意修改或删除;
- API 设计规范:遵循 RESTful API 设计风格,让 API 接口更易于理解和维护。
二、基础准备:项目初始化和依赖安装
如果你已经完成了前两篇的学习,可以直接使用之前创建的fastapi-demo项目。如果没有,请按照以下步骤初始化项目:
- 创建一个新的文件夹,命名为
fastapi-demo; - 在文件夹中创建一个 Python 文件,命名为
main.py; - 在终端中进入
fastapi-demo文件夹,输入以下命令安装依赖:pip install fastapi uvicorn python-multipart
其中,python-multipart是处理表单数据的依赖。
三、核心 HTTP 请求方法详解:GET/POST/PUT/DELETE
接下来,我们用代码示例详解四种核心 HTTP 请求方法的使用场景和实现步骤。
3.1 GET 请求:获取服务器资源
GET 请求是最常用的 HTTP 请求方法,用于获取服务器上的资源。GET 请求的参数通常放在 URL 的查询字符串中(以?开头,参数之间用&分隔),或者放在 URL 的路径中(路径参数)。
3.1.1 路径参数:精确匹配资源
路径参数是 URL 路径中的可变部分,用于精确匹配服务器上的某个资源。比如,/user/123中的123是用户的唯一标识符,通过路径参数可以获取用户 ID 为 123 的用户信息。
打开main.py文件,输入以下代码:
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr, Field
app = FastAPI()
# 模拟用户数据
mock_users = [
{"user_id": 123, "username": "张三", "email": "zhangsan@example.com", "age": 18, "is_active": True},
{"user_id": 456, "username": "李四", "email": "lisi@example.com", "age": 20, "is_active": True},
{"user_id": 789, "username": "王五", "email": "wangwu@example.com", "age": 22, "is_active": False}
]
# 定义用户信息的数据结构
class UserInfo(BaseModel):
user_id: int
username: str
email: EmailStr
age: int = None
is_active: bool = True
# 获取单个用户信息(路径参数)
@app.get("/user/{user_id}", response_model=UserInfo)
def get_user(user_id: int):
"""
获取单个用户信息的接口
:param user_id: 用户的唯一标识符(路径参数,类型为整数)
:return: 用户信息的JSON响应
"""
# 从模拟用户数据中查找用户
for user in mock_users:
if user["user_id"] == user_id:
return user
# 如果没有找到用户,返回404错误
return {"detail": "用户不存在"}, 404
# 获取用户列表(查询参数)
@app.get("/users", response_model=list[UserInfo])
def get_users(page: int = 1, page_size: int = 10, is_active: bool = None):
"""
获取用户列表的接口
:param page: 当前页码(查询参数,可选,默认值为1)
:param page_size: 每页显示的用户数量(查询参数,可选,默认值为10)
:param is_active: 用户是否激活(查询参数,可选,默认值为None表示查询所有用户)
:return: 用户列表的JSON响应
"""
# 过滤用户数据
filtered_users = mock_users
if is_active is not None:
filtered_users = [user for user in filtered_users if user["is_active"] == is_active]
# 分页处理
start_index = (page - 1) * page_size
end_index = start_index + page_size
paginated_users = filtered_users[start_index:end_index]
# 返回用户列表和分页信息
return {
"total": len(filtered_users),
"page": page,
"page_size": page_size,
"data": paginated_users
}
保存文件后,启动 FastAPI 服务:
uvicorn main:app --reload
测试接口:
- 打开 http://127.0.0.1:8000/docs;
- 点击
/user/{user_id}接口旁边的Try it out按钮,输入123,点击Execute,可以看到用户 ID 为 123 的用户信息; - 点击
/users接口旁边的Try it out按钮,输入page=1、page_size=2、is_active=true,点击Execute,可以看到激活状态的用户列表(2 条)。
3.1.2 查询参数:过滤和分页资源
查询参数是 URL 查询字符串中的可变部分,用于过滤、分页或排序服务器上的资源。比如,/users?page=1&page_size=2&is_active=true中的page、page_size、is_active是查询参数,用于获取第 1 页、每页 2 条、激活状态的用户列表。
FastAPI 会自动识别函数参数中不属于路径参数的变量为查询参数。如果查询参数没有默认值,FastAPI 会将其视为必填参数;如果有默认值,FastAPI 会将其视为可选参数。
3.2 POST 请求:提交新资源
POST 请求用于向服务器提交新的资源,比如用户注册、发布文章等。POST 请求的参数通常放在请求体中(JSON 格式或表单数据格式)。
3.2.1 JSON 请求体:提交结构化数据
JSON 请求体是 POST 请求最常用的参数格式,用于提交结构化数据(如嵌套的 JSON 对象)。你可以通过继承 Pydantic 的BaseModel类定义 JSON 请求体的数据结构。
打开main.py文件,输入以下代码:
# 定义用户注册的数据结构
class UserRegister(BaseModel):
username: str = Field(..., min_length=3, max_length=20, pattern=r"^[a-zA-Z0-9_]+$")
email: EmailStr
password: str = Field(..., min_length=8, max_length=20,
regex=r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).*$")
age: int = Field(None, ge=1, le=120)
# 用户注册(JSON请求体)
@app.post("/register", response_model=UserInfo)
def user_register(user: UserRegister):
"""
用户注册的接口
:param user: 用户注册信息(请求体参数,类型为 UserRegister)
:return: 注册成功的响应
"""
# 模拟生成用户ID
new_user_id = max([user["user_id"] for user in mock_users]) + 1
# 构造新用户信息
new_user = {
"user_id": new_user_id,
"username": user.username,
"email": user.email,
"age": user.age,
"is_active": True
}
# 将新用户信息添加到模拟用户数据中
mock_users.append(new_user)
# 返回新用户信息
return new_user
测试接口:
- 打开 http://127.0.0.1:8000/docs;
- 点击
/register接口旁边的Try it out按钮,输入以下 JSON 数据:{ "username": "testuser", "email": "testuser@example.com", "password": "Test1234", "age": 25 } - 点击
Execute,可以看到新用户的信息。
3.2.2 表单数据:提交非结构化数据
表单数据是 POST 请求的另一种常用参数格式,用于提交非结构化数据(如文件上传、HTML 表单数据)。你需要安装python-multipart依赖才能处理表单数据。
打开main.py文件,输入以下代码:
from fastapi import Form
# 用户登录(表单数据)
@app.post("/login")
def user_login(username: str = Form(...), password: str = Form(...)):
"""
用户登录的接口
:param username: 用户名(表单数据,必填)
:param password: 密码(表单数据,必填)
:return: 登录成功的响应
"""
# 模拟登录验证(这里只验证用户名和密码是否为空)
if not username or not password:
return {"detail": "用户名或密码不能为空"}, 400
# 返回登录成功的响应(实际项目中应该返回JWT token)
return {"message": "登录成功", "token": "fake-jwt-token"}
测试接口:
- 打开 http://127.0.0.1:8000/docs;
- 点击
/login接口旁边的Try it out按钮,输入username=zhangsan、password=123456,点击Execute,可以看到登录成功的响应。
3.3 PUT 请求:更新资源
PUT 请求用于更新服务器上的资源,比如修改用户信息、更新文章内容等。PUT 请求的参数通常包括路径参数(用于定位资源)和请求体参数(用于更新资源的内容)。
打开main.py文件,输入以下代码:
# 定义用户更新的数据结构
class UserUpdate(BaseModel):
username: str = Field(None, min_length=3, max_length=20, pattern=r"^[a-zA-Z0-9_]+$")
email: EmailStr = None
age: int = Field(None, ge=1, le=120)
is_active: bool = None
# 更新用户信息(路径参数 + JSON请求体)
@app.put("/user/{user_id}", response_model=UserInfo)
def update_user(user_id: int, user: UserUpdate):
"""
更新用户信息的接口
:param user_id: 用户的唯一标识符(路径参数,类型为整数)
:param user: 用户更新信息(请求体参数,类型为 UserUpdate)
:return: 更新后的用户信息
"""
# 从模拟用户数据中查找用户
for index, existing_user in enumerate(mock_users):
if existing_user["user_id"] == user_id:
# 构造更新后的用户信息
updated_user = existing_user.copy()
# 只有不为None的字段才会更新
if user.username is not None:
updated_user["username"] = user.username
if user.email is not None:
updated_user["email"] = user.email
if user.age is not None:
updated_user["age"] = user.age
if user.is_active is not None:
updated_user["is_active"] = user.is_active
# 替换模拟用户数据中的用户信息
mock_users[index] = updated_user
# 返回更新后的用户信息
return updated_user
# 如果没有找到用户,返回404错误
return {"detail": "用户不存在"}, 404
测试接口:
- 打开 http://127.0.0.1:8000/docs;
- 点击
/user/{user_id}接口旁边的Try it out按钮,输入user_id=123,点击Execute,可以看到用户 ID 为 123 的原始用户信息;
3.4 DELETE 请求:删除资源
DELETE 请求用于删除服务器上的资源,比如删除用户账号、删除评论等。DELETE 请求的参数通常包括路径参数(用于定位资源)和可选的查询参数(用于确认删除操作)。
打开main.py文件,输入以下代码:
# 删除用户账号(路径参数 + 查询参数)
@app.delete("/user/{user_id}")
def delete_user(user_id: int, confirm: bool = False):
"""
删除用户账号的接口
:param user_id: 用户的唯一标识符(路径参数,类型为整数)
:param confirm: 是否确认删除(查询参数,可选,默认值为False)
:return: 删除成功的响应
"""
# 检查是否确认删除
if not confirm:
return {"detail": "请确认删除操作"}, 400
# 从模拟用户数据中查找用户
for index, existing_user in enumerate(mock_users):
if existing_user["user_id"] == user_id:
# 删除用户
del mock_users[index]
# 返回删除成功的响应
return {"message": "用户删除成功"}
# 如果没有找到用户,返回404错误
return {"detail": "用户不存在"}, 404
测试接口:
- 打开 http://127.0.0.1:8000/docs;
- 点击
/user/{user_id}接口旁边的Try it out按钮,输入user_id=101、confirm=true,点击Execute,可以看到用户删除成功的响应。
四、HTTP 请求方法对比表
为了让你更直观地理解四种核心 HTTP 请求方法的区别,我们整理了以下对比表:
| 请求方法 | 语义 | 是否幂等 | 是否安全 | 是否有请求体 | 参数位置 | 常见使用场景 |
|---|---|---|---|---|---|---|
| GET | 获取资源 | 是(多次请求返回相同结果) | 是(不会修改服务器资源) | 可选(通常不包含) | 路径参数、查询参数 | 查询用户信息、获取商品列表、搜索文章 |
| POST | 提交新资源 | 否(多次请求会创建多个资源) | 否(会修改服务器资源) | 是(必须包含) | 路径参数、查询参数、请求体(JSON / 表单数据) | 用户注册、发布文章、上传文件 |
| PUT | 更新资源 | 是(多次请求返回相同结果) | 否(会修改服务器资源) | 是(必须包含) | 路径参数、查询参数、请求体(JSON) | 修改用户信息、更新文章内容、替换商品库存 |
| DELETE | 删除资源 | 是(多次请求返回相同结果) | 否(会修改服务器资源) | 可选(通常不包含) | 路径参数、查询参数 | 删除用户账号、删除评论、删除商品 |
五、进阶提示:下一步可以学什么?
如果你已经掌握了四种核心 HTTP 请求方法的使用,下一步你可以学习以下内容:
- 请求头和响应头:处理 HTTP 请求头和响应头,比如设置跨域资源共享(CORS)、身份验证等;
- 文件上传和下载:用 FastAPI 处理文件上传和下载,支持图片、视频、文档等格式;
- 异步接口:用 async/await 语法实现异步接口,提高系统的吞吐量和响应时间;
- 身份验证和权限控制:用 OAuth2、JWT 等方法实现身份验证,用依赖注入实现权限控制;
- 错误处理:自定义 FastAPI 的错误处理函数,返回更符合业务需求的错误响应。
六、结语:HTTP 请求方法是 API 设计的基础
HTTP 请求方法是 API 设计的基础,它定义了客户端对服务器资源的操作类型,遵循 RESTful API 设计风格可以让 API 接口更易于理解和维护。FastAPI 对四种核心 HTTP 请求方法提供了完整的支持,并且可以通过类型注解自动验证参数和返回值,开发效率非常高。
如果你之前对 HTTP 请求方法的使用感到困惑,希望这篇文章能给你带来帮助。如果你有任何问题或建议,欢迎在评论区留言,我会及时回复。
4128





