HTTP方法详解:GET、POST、PUT、DELETE

目录

[GET、POST、PUT、DELETE 到底分别是干什么的](#GET、POST、PUT、DELETE 到底分别是干什么的)

[1. GET:获取数据](#1. GET:获取数据)

例子

[浏览器为什么最容易访问 GET](#浏览器为什么最容易访问 GET)

[2. POST:创建数据](#2. POST:创建数据)

例子

[为什么创建一般用 POST,不用 GET](#为什么创建一般用 POST,不用 GET)

[3. PUT:整体更新数据](#3. PUT:整体更新数据)

[FastAPI 例子](#FastAPI 例子)

[PUT 的重点](#PUT 的重点)

[4. PATCH:部分更新数据](#4. PATCH:部分更新数据)

例子

[PUT 和 PATCH 的区别](#PUT 和 PATCH 的区别)

[5. DELETE:删除数据](#5. DELETE:删除数据)

例子

[6. 一套完整的 REST 风格接口长什么样](#6. 一套完整的 REST 风格接口长什么样)

[7. 什么叫"不要把动作乱塞进路径里"](#7. 什么叫“不要把动作乱塞进路径里”)

[8. 为什么同一个路径可以对应不同方法](#8. 为什么同一个路径可以对应不同方法)

[9. 一个完整示例:商品模块](#9. 一个完整示例:商品模块)

[10. 在浏览器、Swagger、Postman 里分别怎么测](#10. 在浏览器、Swagger、Postman 里分别怎么测)

浏览器地址栏

[Swagger 文档](#Swagger 文档)

[Postman / Apifox](#Postman / Apifox)

[11. 什么时候该用哪一个](#11. 什么时候该用哪一个)

[用 GET 的场景](#用 GET 的场景)

[用 POST 的场景](#用 POST 的场景)

[用 PUT 的场景](#用 PUT 的场景)

[用 PATCH 的场景](#用 PATCH 的场景)

[用 DELETE 的场景](#用 DELETE 的场景)

[12. Agent 项目里怎么映射这些方法](#12. Agent 项目里怎么映射这些方法)

获取会话列表

获取某个会话详情

创建新会话

发送用户消息

修改会话标题

删除会话

[13. 一个常见误区:POST 不只是"创建"](#13. 一个常见误区:POST 不只是“创建”)

[14. 最后给你一个最好记的口诀](#14. 最后给你一个最好记的口诀)


GET、POST、PUT、DELETE 到底分别是干什么的

你可以先用一个很接地气的类比:

假设你有一个"商品系统"。

  • GET:查看商品

  • POST:新建商品

  • PUT:整体修改商品

  • DELETE:删除商品

再补一个你之后一定会遇到的:

  • PATCH:部分修改商品

1. GET:获取数据

GET 最核心的语义是:

从服务器读取资源,不应该用来修改数据

比如:

  • 获取商品列表

  • 获取某个商品详情

  • 搜索用户

  • 查询订单状态

例子

python 复制代码
from fastapi import FastAPI

app = FastAPI()

@app.get("/items")
async def list_items():
    return [
        {"id": 1, "name": "键盘"},
        {"id": 2, "name": "鼠标"}
    ]

@app.get("/items/{item_id}")
async def get_item(item_id: int):
    return {"id": item_id, "name": "键盘"}

这里:

  • GET /items:查列表

  • GET /items/1:查单个

浏览器为什么最容易访问 GET

因为你在浏览器地址栏里输入网址,本质上默认发的就是 GET 请求。

所以 GET 是最容易直接测试的。


2. POST:创建数据

POST 最常见的语义是:

向服务器提交数据,通常用于新建资源

比如:

  • 创建用户

  • 创建商品

  • 提交聊天消息

  • 创建订单

  • 上传表单

例子

python 复制代码
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class ItemCreate(BaseModel):
    name: str
    price: float

@app.post("/items")
async def create_item(item: ItemCreate):
    return {
        "message": "创建成功",
        "item": item
    }

请求可以是:

复制代码
{
  "name": "键盘",
  "price": 199.0
}

为什么创建一般用 POST,不用 GET

因为 GET 的语义是"读取",而创建会改变服务器状态。

如果你用 GET 去创建数据,那接口设计就会开始发癫:

python 复制代码
@app.get("/create-item")
async def create_item():
    ...

这 technically 也许能跑,但语义上非常不规范。

别人一看会想:"你这是接口,还是惊悚片伏笔?"


3. PUT:整体更新数据

PUT 的核心语义通常是:

用新的完整数据替换旧资源

注意关键词:完整替换

比如你有一个商品:

复制代码
{
  "id": 1,
  "name": "键盘",
  "price": 199.0,
  "stock": 10
}

如果你用 PUT 更新它,通常意味着你要提供这整个资源的新版本,而不是只改一点点。

FastAPI 例子

python 复制代码
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class ItemUpdate(BaseModel):
    name: str
    price: float
    stock: int

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: ItemUpdate):
    return {
        "message": "整体更新成功",
        "item_id": item_id,
        "new_item": item
    }

请求体:

复制代码
{
  "name": "机械键盘",
  "price": 299.0,
  "stock": 8
}

PUT 的重点

它更像:

"把这条记录按我给你的这份完整内容重写一遍"

所以很多规范里会把 PUT 理解为"整体替换"。


4. PATCH:部分更新数据

这个你一定要顺手一起学,因为实际项目里它非常常见。

PATCH 的核心语义是:

只修改资源的一部分字段

比如你只想把价格从 199 改成 299,不想把整个商品都重传一遍。

例子

python 复制代码
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class ItemPatch(BaseModel):
    name: str | None = None
    price: float | None = None
    stock: int | None = None

@app.patch("/items/{item_id}")
async def patch_item(item_id: int, item: ItemPatch):
    return {
        "message": "部分更新成功",
        "item_id": item_id,
        "changed_fields": item.model_dump(exclude_none=True)
    }

请求体可能是:

复制代码
{
  "price": 299.0
}

PUT 和 PATCH 的区别

你可以这样记:

  • PUT:整套换掉

  • PATCH:只修一点

这俩在很多项目里都会同时存在。


5. DELETE:删除数据

DELETE 的语义最直接:

删除某个资源

比如:

  • 删除商品

  • 删除用户

  • 删除会话

  • 删除任务

例子

python 复制代码
from fastapi import FastAPI

app = FastAPI()

@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
    return {
        "message": "删除成功",
        "item_id": item_id
    }

调用:

复制代码
DELETE /items/1

意思就是删除 id=1 的商品。


6. 一套完整的 REST 风格接口长什么样

假设你做一个商品模块,最常见的设计会像这样:

操作 HTTP 方法 路径 含义
获取商品列表 GET /items 查所有商品
获取单个商品 GET /items/{item_id} 查某个商品
创建商品 POST /items 新建商品
整体更新商品 PUT /items/{item_id} 全量替换商品
部分更新商品 PATCH /items/{item_id} 局部修改商品
删除商品 DELETE /items/{item_id} 删除商品

这就是非常典型的 REST 风格设计。

你可以发现一个规律:

  • 路径表示资源

  • HTTP 方法表示动作

而不是把动作写进路径里。


7. 什么叫"不要把动作乱塞进路径里"

初学者很容易这样设计:

复制代码
/getItems
/createItem
/updateItem
/deleteItem

这个当然能用,但不够规范。

更推荐的是:

复制代码
GET    /items
POST   /items
PUT    /items/{item_id}
DELETE /items/{item_id}

原因很简单:

  • 路径表示"你在操作谁"

  • 方法表示"你要干什么"

也就是说:

  • /items 是资源

  • GET/POST/PUT/DELETE 是动作

这样接口会更统一,也更容易扩展。


8. 为什么同一个路径可以对应不同方法

比如这两个:

python 复制代码
@app.get("/items")
async def list_items():
    ...

@app.post("/items")
async def create_item():
    ...

路径都是 /items,但不会冲突。

因为 FastAPI 区分路由时,不只是看路径,还看:

  • 路径

  • HTTP 方法

所以:

  • GET /items → 查列表

  • POST /items → 创建数据

这俩是不同的接口。


9. 一个完整示例:商品模块

我给你写一个稍微完整点的版本,你一看就会更顺。

python 复制代码
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# 模拟数据库
items_db = {
    1: {"id": 1, "name": "键盘", "price": 199.0, "stock": 10},
    2: {"id": 2, "name": "鼠标", "price": 99.0, "stock": 20},
}


class ItemCreate(BaseModel):
    name: str
    price: float
    stock: int


class ItemUpdate(BaseModel):
    name: str
    price: float
    stock: int


class ItemPatch(BaseModel):
    name: str | None = None
    price: float | None = None
    stock: int | None = None


@app.get("/items")
async def list_items():
    return list(items_db.values())


@app.get("/items/{item_id}")
async def get_item(item_id: int):
    return items_db.get(item_id, {"error": "商品不存在"})


@app.post("/items")
async def create_item(item: ItemCreate):
    new_id = max(items_db.keys()) + 1
    new_item = {"id": new_id, **item.model_dump()}
    items_db[new_id] = new_item
    return new_item


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: ItemUpdate):
    if item_id not in items_db:
        return {"error": "商品不存在"}
    items_db[item_id] = {"id": item_id, **item.model_dump()}
    return items_db[item_id]


@app.patch("/items/{item_id}")
async def patch_item(item_id: int, item: ItemPatch):
    if item_id not in items_db:
        return {"error": "商品不存在"}

    update_data = item.model_dump(exclude_none=True)
    items_db[item_id].update(update_data)
    return items_db[item_id]


@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
    if item_id not in items_db:
        return {"error": "商品不存在"}
    deleted = items_db.pop(item_id)
    return {"message": "删除成功", "deleted_item": deleted}

这个例子基本把 CRUD 串起来了:

  • Create → POST

  • Read → GET

  • Update → PUT/PATCH

  • Delete → DELETE


10. 在浏览器、Swagger、Postman 里分别怎么测

浏览器地址栏

适合测 GET:

  • http://127.0.0.1:8000/items

  • http://127.0.0.1:8000/items/1

因为浏览器默认 GET。

Swagger 文档

FastAPI 启动后访问:

复制代码
http://127.0.0.1:8000/docs

这里最适合测:

  • GET

  • POST

  • PUT

  • PATCH

  • DELETE

因为它能直接选方法、填参数、发请求。

Postman / Apifox

适合做更真实的接口调试,尤其是:

  • 带 JSON body 的 POST/PUT/PATCH

  • 带 Header 的请求

  • 带 Token 的认证接口


11. 什么时候该用哪一个

这个你一定要形成直觉。

用 GET 的场景

你只是"看"数据,不改服务器状态。

比如:

  • 获取聊天记录

  • 查看任务列表

  • 查询某个用户资料

  • 搜索商品

用 POST 的场景

你在"提交新数据"或触发一个创建型动作。

比如:

  • 新建会话

  • 发送一条聊天消息

  • 创建订单

  • 上传文件

  • 提交表单

用 PUT 的场景

你要把某个对象整体更新。

比如:

  • 用户资料整条替换

  • 商品完整信息覆盖更新

用 PATCH 的场景

你只改少数字段。

比如:

  • 只修改昵称

  • 只改任务状态

  • 只改价格

  • 只改某条记录的备注

用 DELETE 的场景

你要删除某个资源。

比如:

  • 删除会话

  • 删除任务

  • 删除商品

  • 删除评论


12. Agent 项目里怎么映射这些方法

你现在在学 agent 应用,这里我顺手给你对应一下,会更有感觉。

假设你有一个聊天系统:

获取会话列表

python 复制代码
@app.get("/conversations")

获取某个会话详情

python 复制代码
@app.get("/conversations/{conversation_id}")

创建新会话

python 复制代码
@app.post("/conversations")

发送用户消息

python 复制代码
@app.post("/conversations/{conversation_id}/messages")

修改会话标题

python 复制代码
@app.patch("/conversations/{conversation_id}")

删除会话

python 复制代码
@app.delete("/conversations/{conversation_id}")

你会发现,思路是一样的:

  • 路径写资源

  • 方法写动作

这就是接口设计的骨架。


13. 一个常见误区:POST 不只是"创建"

这个点我得顺手拧正一下。

虽然最典型的 POST 是"创建资源",但在实际项目里,POST 也常用来做:

  • 登录

  • 执行某个复杂动作

  • 提交推理请求

  • 调用 AI 对话生成

  • 上传和处理文件

比如:

python 复制代码
@app.post("/chat")
async def chat(req: ChatRequest):
    ...

因为"对话生成"不太像简单的资源读取,也不一定适合 PUT/DELETE,所以 POST 很常见。

也就是说:

  • GET 主要是读

  • POST 最常见是创建,也常用于"提交一个动作"

  • PUT/PATCH 是更新

  • DELETE 是删除


14. 最后给你一个最好记的口诀

你可以先记成这套:

  • GET:拿数据

  • POST:交数据 / 建数据

  • PUT:整条改

  • PATCH:局部改

  • DELETE:删数据

再进一层理解就是:

  • 路径表示资源

  • 方法表示操作

  • 不要把动作乱写进路径

  • 让接口设计尽量统一

相关推荐
Joker Zxc1 小时前
【前端基础(Javascript部分)】4、JavaScript的分支语句
开发语言·前端·javascript
zh路西法1 小时前
【宇树机器人强化学习】(一):PPO算法的python实现与解析
python·深度学习·算法·机器学习·机器人
小钻风33661 小时前
Optional:告别NullPointerException的优雅方案
开发语言·python
科技块儿2 小时前
多语言技术栈如何共用IP离线库?Java、Python、Go 的加载实践
java·python·tcp/ip
fawubio_A2 小时前
毕业设计 深度学习卷积神经网络垃圾分类系统
python·cnn·毕业设计·毕设
开开心心就好2 小时前
跨平台高速下载工具,支持浏览器功能强大
运维·服务器·windows·pdf·旅游·媒体·1024程序员节
chools2 小时前
一篇文章带你搞懂Java“设计模式”! - - 超长文(涵盖23种)万字总结!【汇总篇】
java·开发语言·设计模式
玖釉-2 小时前
解密图形渲染的性能原罪 —— Draw Call
c++·windows·图形渲染
与虾牵手2 小时前
大模型流式输出 Streaming API 完整教程:从原理到踩坑,一篇搞定
python·aigc·ai编程