把本来该用 PUT 的接口改成 POST 不会立刻炸,但会把 HTTP 协议层白送给你的“幂等性 + 缓存键 + 中间件优化”三张免费护身符扔掉,换来 4 个可预见的长期暗坑:
---
1. 幂等语义丢失 → 重试即灾难
PUT 规定“多次整体覆盖结果一样”,网关、SDK、浏览器重试都心安理得;
POST 不保证幂等,默认不重试。网络一抖,前端 5xx → 用户狂点 → 后端产生 5 份重复数据。
2. 缓存键立刻失效 → 带宽多花冤枉钱
浏览器/CDN 把 URI 当缓存键时,方法不同就是不同资源。
你把 PUT /products/123 换成 POST /products/123,缓存全部失效,每次回源,流量账单 +30% 不是段子。
3. 网关/限流规则失灵 → 粒度变粗
原来可以GET /products/* → 只读,限流 1000/s
PUT /products/* → 更新,限流 200/s
全改成 POST 后只剩一条 /products/*,读写混打,大促瞬间把写接口冲垮。
4. 日志排障成本翻倍
ELK 里清一色 POST /products/123 200,想区分“创建”“全量更新”“部分更新”必须再解 body,凌晨 3 点排障想骂人。
---
真实事故
- 某 SaaS 2022 年把“全量更新配置”从 PUT 换成 POST,Spring-Retry 默认不重试,结果机房 3 s 抖动,1.2 w 份配置未同步,客户面板白屏 20 min,SLA 赔钱 50 w。
- 内容平台把“替换文章”改 POST 后,CDN 命中率掉 40%,每月多 80 TB 回源,账单直接 +1.2 w/月。
---
一句话结论
“能 PUT 就 PUT,把 POST 留给真正‘新增’或‘非幂等动作’;否则重试、缓存、限流、排障的锅,最后都是你自己背。”