幂等性
幂等性保证多次执行同一操作与执行一次产生相同的结果。在支付和转账 API 的场景中,这一特性至关重要:如果在您发送转账请求之后但收到响应之前发生网络故障,您可以安全地重试相同的请求,而不会产生重复转账的风险。
Idempotency-Key 请求头
要使请求具有幂等性,请在请求中包含 Idempotency-Key 请求头并附带唯一标识符:
| 请求头 | 必需 | 说明 |
|---|---|---|
Idempotency-Key | 建议 | 标识此逻辑操作的唯一键(UUID v4)。服务器使用此键来检测和去重重试请求。 |
该键必须是不超过 128 个字符的字符串。我们建议使用 UUID v4 以确保唯一性。
支持的端点
幂等性行为因 HTTP 方法而异:
| 方法 | 默认幂等 | 支持 Idempotency-Key | 备注 |
|---|---|---|---|
GET | 是 | 否 | 读取操作天然幂等。重复 GET 返回相同数据。 |
DELETE | 是 | 否 | 删除已删除的资源返回一致的结果。 |
POST | 否 | 是 | 创建操作默认不幂等。使用 Idempotency-Key 使其可安全重试。 |
PUT | 是 | 否 | 全量资源更新天然幂等。 |
PATCH | 视情况而定 | 可选 | 部分更新是否幂等取决于具体操作。 |
POST 端点
Idempotency-Key 请求头主要为创建资源的 POST 端点设计,如 /api/v1/transfer/command/create。这些操作最容易因重试而产生重复。
工作原理
当您在请求中包含 Idempotency-Key 请求头时,服务器遵循以下流程:
1. 收到带有 Idempotency-Key 的请求
2. 检查此键是否已被使用
├── 新键:
│ ├── 正常处理请求
│ ├── 存储键、请求体哈希和响应
│ └── 返回响应
└── 已存在的键:
├── 将请求体哈希与存储的进行比较
├── 如果请求体匹配 → 返回存储的响应(不重新处理)
└── 如果请求体不同 → 返回 409 Conflict(键冲突)
3. 键在 24 小时后过期服务器会将幂等键与响应的关联存储 24 小时。在此窗口内,任何使用相同键和相同请求体的重试都将返回原始响应,而不会重新执行操作。
键生成
使用 UUID v4 生成幂等键。每个键必须对应一个唯一的逻辑操作。
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000各语言的键生成方式:
示例:防止重复转账
考虑这样一个场景:您需要创建一笔转账,并希望确保即使需要重试也不会产生重复。
第一步: 在请求前生成一个幂等键。
第二步: 在转账创建请求中携带该键。
第三步: 如果请求因网络错误失败,使用 相同的 键和请求体重试。
初始请求或重放请求的成功响应:
{
"version": "1.3.0",
"timestamp": 1709337600000,
"success": true,
"code": "2000",
"message": "SUCCESS",
"data": {
"transferId": "txn_789xyz",
"status": "COMPLETED",
"amount": "100.00",
"currency": "USD"
}
}错误处理
键冲突(请求体不同)
如果您使用同一个幂等键但 不同的 请求体重发请求,服务器将返回 409 Conflict 和错误码 T1023:
{
"version": "1.3.0",
"timestamp": 1709337600000,
"success": false,
"code": "T1023",
"message": "DUPLICATE_REQUEST",
"data": null
}这是一种安全机制。每个幂等键与特定的请求体哈希绑定。您不能重用一个键来执行不同的操作。
键过期
幂等键在 24 小时 后过期。过期后,同一个键可以再次使用——但服务器会将其视为新请求,而非重放。避免在过期后依赖键重用;始终为新操作生成新键。
网络错误
如果您收到网络超时或连接错误(完全没有 HTTP 响应),可以安全地使用相同的幂等键重试。服务器要么:
- 从未收到请求——会将其作为新请求处理。
- 已收到并处理——会返回缓存的响应。
两种情况下都不会创建重复转账。
最佳实践
在重试循环之前生成键
在进入重试逻辑 之前 创建幂等键。如果每次重试都生成新键,您将失去去重保证,并可能创建重复资源。
每个逻辑操作使用一个键
每个不同的业务操作应该有自己的幂等键。不要重用前一笔转账的键来创建新的不同转账。不同的操作需要不同的键。
键过期窗口
键的有效期为 24 小时。设计您的重试逻辑使其在此窗口内完成。对于大多数使用场景,使用指数退避(1 秒、2 秒、4 秒)且最多 3-5 次重试的策略完全可以在此限制内完成。
存储键以便对账
创建转账时,在您的系统中将幂等键与请求一起记录。如果您需要调查转账是否已创建,可以通过查找该键来确定服务器是否已处理该请求。
:::caution 不要将 Idempotency-Key 用作 Nonce Idempotency-Key 和 X-Nonce 请求头用途不同。Nonce 是 HMAC 签名的一部分,必须在每个 HTTP 请求(包括重试)中唯一。幂等键在同一逻辑操作的多次重试中必须 相同。切勿将它们设为相同的值。 :::