假设我正在创建一个 REST API,并且我的 POST 方法创建一个新订单。我想在我的 API 中使用超媒体,向客户端提供可用操作列表,并且 POST 方法的路径应包含 IdempotencyKey(因此 IdempotencyKey 是在服务器上创建的,而不是在客户端上创建的)。例如:
{
// ...
"actions": [
{
"name": "createOrder",
"path": "/api/v1/orders/create/<idempotency-key-uuid>",
"method": "POST"
}
]
}
如果用户直接进入“创建订单”页面,您实际上如何获得此初始响应?我是否应该在页面初始加载时发出某种获取请求(以获取“createOrder”操作的路径)?
当用户单击“创建”按钮时会发生什么,因此发出 POST 请求,然后发生了一些不好的事情(丢失连接、某种超时)。客户端没有得到任何响应,但新订单仍然被创建。用户刷新页面以重试(以创建订单)。如果订单已创建,我们应该获取新的 IdempotencyKey,如果尚未创建,我们应该获取相同的 IdempotencyKey,对吗?有没有办法根据实际发生的情况在服务器上生成相同或新的 IdempotencyKey?看起来它必须取决于服务器的状态,但我无法真正弄清楚正确的实现是什么。
我从来没有遇到过专门拥有
IdempotencyKey
的想法 - 假设它与 ObjectKey
/ UniqueID
/ EntityKey
不同。
如果对象的唯一性由服务器控制,那么通常客户端只需调用
/api/v1/orders/create
,以便“服务器”可以完成其任务。包括生成一个新的唯一 ID,响应可能会将其包含在元数据中。
如果用户直接进入“创建订单”页面,您实际上如何获得此初始响应?
不知道 - 听起来复杂又脆弱。 我需要知道为什么需要这种方法而不是我上面描述的更常见的方法。 我假设目标是避免在意外发送两个非常相似的“创建”请求时创建重复的对象?
用户刷新页面重试(创建订单)。如果订单已创建,我们应该获得新的 IdempotencyKey,如果订单尚未创建,我们应该获得相同的 IdempotencyKey,对吧?
这个接受的答案这里建议客户端设置一个唯一的ID,无论它喜欢什么,并且服务器知道只允许它的一个实例(为了强制唯一性,这并不意味着它必须生成它) 。我不清楚答案所指的 ID 是
ObjectID
还是 IdempotencyKey
。 在您的场景中,您需要保留相同的 IdempotencyKey,否则它将看起来像一个新请求。
同一问题的其他答案讨论了 POE,这似乎与您最初建议的一致。
另一种方法是让服务器端服务具有足够的智能来查看传入数据是否已经存在,这可以仅基于传入对象数据,或者也可以获取请求日期/时间和请求日期/时间等信息。对象创建日期/时间考虑在内。