🌍 译介 · 编译自 Nordic APIs

API 幂等性与安全性:用对 HTTP 方法才安全

「幂等」到底指什么?为什么 GET 必须是只读、POST 不能幂等?本文编译自 Nordic APIs(2018-09-14,作者 Kristopher Sandoval),用「西班牙语问时间」的比喻讲清幂等与安全的区别,列出 HTTP 方法的幂等/安全矩阵,并用「车库门被误开」「重复下单」两个真实教训说明:用错方法会很危险。

📅 更新于 2026-07-23 ⏱ 约 6 分钟阅读 🏷 译介
免费试用 YesApi Pro 查看全部定价 →
🌐本文由 YesApi Pro 团队编译Nordic APIs 的文章《Understanding Idempotency and Safety in API Design》,原作者 Kristopher Sandoval(原文发布于 2018-09-14)。版权归原作者所有,内容仅供学习参考。查看英文原文 →
📌 核心结论
幂等=同请求重复多次返回「形式」一致(值可变);安全=不改服务器状态(只读)。安全的方法必然幂等,但幂等的不一定安全。GET/PUT/DELETE 幂等,POST/PATCH 不幂等。用 GET 去改状态(如触发开关)是反模式,会把同步机制变成定时炸弹。
📑 本文目录
  1. 什么是幂等性
  2. 幂等性与安全性
  3. 为什么不能让一切都幂等
  4. 理论不等于实践:用错方法的代价
  5. 契约、标准化与信任
  6. 结论
01

一、什么是幂等性

一句话:一个操作重复调用多次,产生的结果形式一致,它就是幂等的。同样的请求做两次、两千次、两百万次,返回应当长得一样。这里的关键是「形式(return form)」而非「值(return value)」。

举个比方:用西班牙语问「¿que hora es?(几点了)」,答案会随时段变(值变了),但回答的形式不会变——不会突然改用「柠檬」当单位、或改用法语回答。无论问多少遍,它都该用西班牙语、同样的语法结构回应。API 也一样:调用的「形式」不该随请求而变,返回值可以不同,但结构、加密方式、字段必须可预期。

02

二、幂等性与安全性

两者常被混用,但不同。安全(safe)指方法不改变服务器状态,即只读。安全方法本身不产生变更(日志更新那是服务器自己干的,不是请求改的)。

关系像「正方形是矩形,矩形不一定是正方形」:安全的方法因为不改变状态,返回形式必然一致,所以安全 ⇒ 幂等;但一个方法可以幂等却仍改变状态(如 DELETE 删完再删,返回形式一样),所以幂等 ⇏ 安全。下表给出常见 HTTP 方法的归类:

方法幂等安全说明
GET读取,不改状态
HEAD同 GET 仅头
PUT整体覆盖,重复结果一致
DELETE删了再删,返回一致
POST每次创建新资源
PATCH部分更新,多次结果可能不同
03

三、为什么不能让一切都幂等

既然幂等这么好,为啥不所有方法都做成幂等?因为有时我们既要值变、也要形式变POST 本质就是「导致服务器状态变化、且期望返回形式也变」——如果 POST 幂等,意味着每次提交的东西早已存在于服务器,那它就不是 POST 了。所以 POST 既不能幂等也不安全,这是它的本职。

DELETE 看似例外,其实仍幂等:删掉资源是「值」的变化,但响应形式一致(都是「存在/不存在、是否删除成功」的错误码)。无论怎么删,返回都一样。这正说明:搞懂概念,才能看出「看似不幂等的东西其实幂等」。

04

四、理论不等于实践:用错方法的代价

最大 caveat:理论不等于实践。一个本该幂等的操作,若被开发者用不幂等的方式实现,就成了不幂等操作——这本质是坏设计。例子一:某 API 用 GET 去切换车库门继电器。GET 本该安全幂等,但这里它被用来触发动作。Apple 多设备同步机制一旦打开含该 GET 的标签页,就会自动触发开门——用户连续几晚被半夜开门搞懵。正确做法是用 PUT 改状态、用 GET 只读状态。

例子二(更严肃):支付接口。正确设计是点一次提交 → 生成 POST 更新订单;之后重复点击用 GET 只返回订单状态。若不做这层,用户点 100 次就生成 100 个订单。这不是幂等本身的问题,而是设计问题——但足以说明:用错方法既费钱又危险,还会直接瓦解你的代码库。

05

五、契约、标准化与信任

幂等/安全带来的核心价值,是与用户之间的「契约」。客户端应当能信任你的 API:调用 GET 不会改状态、调用 PUT 重复安全。不遵循这套,等于要求用户既盲信你、又得会「读心」——知道系统边界、知道什么安全什么不安全。这大大复杂化了用户与客户端的关系。契约的责任在开发者这一侧,不在客户端。

06

六、结论

不按幂等且安全的方式设计,是危险的,也是用错了工具的本意。HTTP 方法各有专责,硬让它们干反目的的事毫无意义——GET 不是用来干 POST 的活的,所以两者才都存在。建立正确认知、落实正确设计,能改善体验、提升系统整体强度;忽视这些,轻则混乱,重则失败。

译者实战注 落地建议与延伸

需要快速落地?

YesApi Pro 私有部署、源码交付、当天上线,帮您把方案变为现实。

立即预约演示 →

常见问题

安全=不改服务器状态(只读),幂等=重复调用返回形式一致。安全必然幂等,但幂等可能改状态(如 DELETE),所以幂等不一定安全。

POST 的本职是「每次创建新资源、状态与返回都变」,若它幂等,就意味着数据早已存在,违背了 POST 的语义。

GET 应为安全幂等(只读),用来触发写操作(如开开关、下单)会在同步/重试/预取时被意外重复执行,是经典反模式。

YesApi Pro 网关层可按接口语义约定方法(读用 GET、写用 POST/PUT),并支持按客户端/请求做幂等键与去重,避免重复提交造成重复计费或状态错乱。
📚

继续阅读