Skip to content

HTTP方法

HTTP方法(GET、DELETE、PUT、PATCH、POST)

第一层:基础认知(CRUD 标准映射)

这是最基础的,你肯定知道,但面试时要快速、准确地说出来:

HTTP方法对应操作典型语义是否携带Body
GET查(Read)获取资源列表或单个资源否(规范不建议)
POST增(Create)创建新资源(服务端生成ID)
PUT改(Update / 全量替换)全量更新资源(客户端指定完整资源)
PATCH改(Update / 部分修改)局部更新资源(只传要改的字段)
DELETE删(Delete)删除指定资源通常否

第二层:进阶原理(决定选型的核心 —— 安全 & 幂等)

这是面试官最看重的底层逻辑。你在回答选型时,必须先抛出这两个概念:

  • 安全(Safe):不会修改服务器状态。只有 GET 是安全的(HEAD/OPTIONS 也是,但日常不提)。
  • 幂等(Idempotent):无论执行多少次,结果都一样。
HTTP方法安全性幂等性核心结论(面试背下来)
GET✅ 安全✅ 幂等只查不改,放心缓存和重试
DELETE❌ 不安全✅ 幂等删1次和删N次,最终状态都是“已删除”(响应可能不同,但状态一致)
PUT❌ 不安全✅ 幂等全量覆盖,执行N次结果相同
PATCH❌ 不安全不保证幂等(取决于实现)如果实现是“设置 age=18”,则是幂等的;如果是“age += 1”(自增),则非幂等
POST❌ 不安全❌ 非幂等每次创建一条新数据,结果不同

面试话术:“选型时,我会优先从语义和幂等性出发。GET 只做查询;POST 处理非幂等的创建;PUT 用于全量覆盖;PATCH 做局部更新,但要小心业务逻辑是否幂等;DELETE 虽然是幂等的,但要做好权限和级联处理。”


第三层:实战决策树(到底怎么选?场景对照)

别再死记硬背,直接套这个业务决策逻辑:

  1. 我要拿数据,服务器状态不变?GET

    • 注意:GET 也可以传参(Query String 或路径变量),但绝对不要用 GET 传大 JSON Body(网关/代理会拒绝)。
  2. 我要新增一条数据,ID 由后端生成(如订单、报告)?POST

    • 注意:POST 非幂等,不能自动重试(否则重复下单)。
  3. 我要更新数据,且客户端知道完整的最终状态(覆盖)?PUT

    • 例如:PUT /user/1 传入完整 { name, age, address }
    • 风险:如果只传了 { age },PUT 会把 nameaddress 置空(因为全量替换)。
  4. 我要更新数据,只改其中几个字段(增量更新)?PATCH

    • 例如:PATCH /user/1 只传 { age: 18 }
    • 注意:PATCH 是否幂等取决于实现。如果你传的是 { "op": "increment", "field": "age" },那就是非幂等的。
  5. 我要删除某个特定资源?DELETE

    • 即使第二次删除返回 404,资源状态依然是“已删除”,所以是幂等的。

第四层:结合你的简历(实际项目怎么用)

面试官问:“你简历里的 IRMP 报告生成接口,为什么用 POST 而不是 PUT?”

你的回答(结合幂等键)

“在 IRMP 平台,/api/report/generate生成一份全新报告,每次生成都会产生新的报告 ID 和 PDF 文件。这是典型的 非幂等创建 操作,所以我用 POST

但为了处理网络超时导致的重复提交,我们没有依赖 HTTP 方法的幂等性,而是在请求头中增加了 Idempotent-Key(幂等键)。后端根据这个 Key 做去重,从而将非幂等的 POST 在业务层变为幂等。前端代码实现如下:

javascript
// 前端请求拦截器(IRMP 项目)
axios.interceptors.request.use(config => {
  if (config.method === 'post') {
    // 用 uuid 生成幂等键,存在 localStorage 防止刷新丢失
    let idempotentKey = localStorage.getItem('report_idempotent_key');
    if (!idempotentKey) {
      idempotentKey = uuidv4();
      localStorage.setItem('report_idempotent_key', idempotentKey);
    }
    config.headers['Idempotent-Key'] = idempotentKey;
  }
  return config;
});
```”

再补一个查询和更新的例子

  • IAMP 点云数据查询GET /api/pointcloud?tunnelId=xxx(查询,幂等)
  • WeLink 用户头像更新(全量)PUT /api/user/avatar(传入完整图片 Base64,全量覆盖)
  • MMMP 告警配置修改(只改开关)PATCH /api/alarm/config(只传 { enabled: false }

第五层:面试官的“变态追问”与你的回应

追问 1:“既然 GET 不能带 Body,那我要传很复杂的查询条件(比如多条件筛选 + 排序 + 分页)怎么办?”

标准做法是用 Query String(查询字符串),如 GET /api/reports?page=1&size=20&status=done&sort=desc。如果条件非常复杂(超过 URL 长度限制 2048 字符),我会改用 POST 请求来查询(即 POST /api/reports/search),虽然不符合 RESTful 严格规范,但在工程上这是业界通用的妥协方案(如 Elasticsearch 的 _search API)。”

追问 2:“我调用 DELETE,第二次返回 404,它还算幂等吗?”

算! 幂等关注的是服务器最终状态,而不是每次的响应码。第一次删除后资源没了,第二次再删资源还是‘没了’状态,所以是幂等的。安全性和幂等性定义的是状态,而非状态码。

追问 3:“PUT 和 PATCH 到底怎么选?后端同事让我统一用 PUT 怎么办?”

“我会坚持用 PATCH 做局部更新。因为如果用 PUT 做局部更新,前端必须把整个对象传给后端(包括没变的字段),这会导致:

  1. 带宽浪费(尤其是大对象)。
  2. 并发冲突风险:用户 A 只改了年龄,但把全量数据传回去,可能会覆盖掉用户 B 刚修改的名字(丢失更新问题)。PATCH 配合 If-Match(ETag)能更好地做并发控制。

我会跟后端同事沟通,建议 PUT 只用于完全替换PATCH 用于增量修改,这是 RESTful 规范明确建议的。”


面试现场组合技(最终总结)

“面试官,总结来说,我选用 HTTP 方法的核心逻辑是 ‘语义匹配 + 幂等性兜底’

  • GET:安全幂等,只查不改。
  • POST:非幂等,用于新建资源。绝不自动重试,必须配合业务层的幂等键。
  • PUT:幂等,用于全量覆盖。客户端必须传完整资源。
  • PATCH:非严格幂等,用于局部更新。节省带宽,但要做好并发控制(版本号/ETag)。
  • DELETE:幂等,删除资源。

在实际开发中,我严格按照这套规范设计接口。例如 IRMP 的报告生成(POST + 幂等键)、用户信息修改(PUT 全量 / PATCH 增量),都是这套方法论的具体落地。”

最近更新