← 中文资源

简体中文版本

为写接口添加幂等键

接收 Idempotency-Key,存储请求指纹与响应,在重试时返回原始结果而不是重复创建资源。

阅读英文原文

重试契约

客户端在写请求中发送 Idempotency-Key: <opaque value>。服务端把该键视为逻辑操作的标识:同一键与同一请求体重复到达时,不得产生第二次副作用。

CREATE TABLE idempotency_keys (
  key text PRIMARY KEY,
  request_hash text NOT NULL,
  status text NOT NULL,
  response jsonb,
  created_at timestamptz NOT NULL DEFAULT now(),
  expires_at timestamptz NOT NULL
);

步骤

  1. 对写接口要求客户端提供幂等键,限制长度并拒绝缺失或格式非法的值。
  2. 在执行副作用之前,用唯一约束原子地写入 key、请求体哈希和 in_progress 状态;使用 INSERT ... ON CONFLICT DO NOTHING RETURNING 抢占键。
  3. 如果键已存在且请求哈希相同,返回已存储的响应;哈希不同则返回 409,不执行副作用。
  4. 执行完成后存储最终状态与响应,并按客户端重试窗口设置过期时间;用相同请求发送两次验证只产生一个资源。

验证

  • 第一次请求创建资源并保存响应。
  • 相同键重复请求返回相同资源 ID。
  • 相同键不同请求体返回 409。
  • 并发重复请求只产生一次副作用。
  • 过期键会被清理,不再重放。

范围与限制

只对非幂等写操作使用幂等键,例如订单、支付和 Webhook 触发的动作;GET、PUT、DELETE 按 HTTP 语义已经幂等。键是不透明的,必须限制长度,并保留得比客户端最大重试窗口更久。不要把键当作认证或授权凭据;存储完整响应时也要避免泄露敏感数据。