Sign inGet Started

幂等性

当连接失败导致您无法确定请求是否成功时,请使用 Idempotency-Key。其保证是恰好一次接受:在 3 小时保留窗口内,使用相同键和相同请求的重试必须解析为同一个已接受的操作,即使您丢失了原始响应。

工作原理

幂等性是可选启用的。在支持的 POST、PATCH、PUT 或 DELETE 请求中添加 Idempotency-Key 请求头。未携带该请求头的请求将正常处理,不进行去重。GET 请求会忽略该请求头。

在客户 API 上,工作区级和组织级的变更操作支持下文所述的响应重放。仅限用户的操作、无作用域的未认证操作以及流式操作不受此机制影响。具有独立重放契约的操作会在其参考页面中定义自身行为。例如,创建语音通话在您提供键时会保留原始接受快照,用于匹配的重试。

SDK 会为每个变更调用生成一个键,并在自动重试(包括创建通话)时复用该键。自动 SDK 重试无需您提供键。当一个预期操作跨越多次独立的 SDK 调用时(例如重启应用后的重试),请提供您自己的键。以下示例展示的就是这种场景。

await bird.email.send(
  {
    from: "hello@yourdomain.com",
    to: ["delivered@messagebird.dev"],
    subject: "Welcome!",
    html: "<p>Thanks for signing up.</p>",
  },
  { idempotencyKey: "welcome-user/usr_abc123" },
);

键可以是任何非空字符串,最长 255 个字符。空的请求头值会跳过去重。推荐的格式是从您自身实体派生的确定性键,<event-type>/<entity-id>(例如 welcome-user/usr_abc123),这样跨进程重启的重试可以共享同一个键;每个逻辑操作使用一个随机 UUID 也可以。Bird SDK 会为每个变更请求自动生成 UUID 键,并在其内部重试中复用。

键的作用域为您的工作区;在组织级端点上,作用域为您的组织。已完成的响应会保留 3 小时;超过该窗口后的重试可能会作为新请求处理。如果过期后原始操作的结果仍未知,请将其保持为未决状态,并在再次发送前先核对其结果。

重放

三小时内的匹配重试必须解析为原始操作。如果其响应已被保留,API 会返回相同的状态码和响应体,而不会接受另一个操作。重放的响应会携带一个额外的响应头,方便您将其与首次处理的响应区分开:

代码示例
HTTP/1.1 202 Accepted
Idempotency-Replay: true

保留的响应可能包含 4xx 拒绝。修正请求时请使用新键:如果该请求的拒绝已被保留,未更改的重试会重放该拒绝,而更改后的请求会返回 409 E01005 IdempotencyKeyReuse。5xx 响应不会作为已完成的响应保留。恰好一次接受的保证同样适用于这些错误之后的重试。

失败场景

场景响应
相同键、相同请求,原始响应在保留期内仍被保留响应通过 Idempotency-Replay: true 重放
相同键、不同的请求体或端点409,E01005 IdempotencyKeyReuse
相同键,原始请求仍在处理中409,E01004 RequestInProgress
键超过 255 个字符,且端点声明了该请求头422,E01001 ValidationError
幂等性保护在执行前不可用503,E01033 IdempotencyUnavailable;此次尝试未被执行

使用已完成的键发送不同的请求会被视为客户端 bug:Bird 会立即返回 409,而不是静默地返回一个与您发送内容不匹配的响应。请为新请求生成新键。比较范围涵盖方法、端点、路径和查询参数以及原始请求体,包括 JSON 空白字符。多部分上传会比较部分名称、文件名和内容;边界和部分顺序不影响重放。

RequestInProgress 表示使用相同键的并发请求尚未完成,通常是因为客户端超时设置过短,在第一次尝试仍在处理时就发起了重试。请稍等片刻,再使用相同的键和请求重试。参见错误了解包装这些错误的错误响应格式。

不会被缓存的内容

5xx 响应不会作为已完成的响应保留。 请在三小时内使用有上限的退避策略,以相同的键和完全相同的请求进行重试。即使原始响应已丢失,恰好一次接受的保证仍然适用。

如果幂等性保护在执行前不可用,API 会返回 503 E01033 IdempotencyUnavailable,且不会执行此次尝试。每次重试都应保留该键。此错误不描述使用相同键的先前尝试的结果。

实践指南

  • 为每个逻辑操作生成一个键,并在该操作的每次 HTTP 尝试中复用它。
  • 遇到网络错误、超时和 5xx 时,在三小时内使用有上限的指数退避进行重试,并保留相同的键和完全相同的请求。
  • 当重试次数用尽或保留期过期时,将结果未知的操作保持为未解决状态。在使用旧键或新键提交另一个操作之前,请先核对该操作的结果。
  • 对于消息发送,请在请求被接受后检查消息状态以确认是否送达。
  • 将 409 IdempotencyKeyReuse 视为键生成中的错误,不要重试。
  • 键在变更操作中是可选的。需要重试保护时使用键;在 GET 请求中可以省略。

后续步骤

继续查看此主题的文档、指南和示例。