如何在同时接收具有相同 id 的多个请求时保持 API 幂等? [英] How to keep an API idempotent while receiving multiple requests with the same id at the same time?

查看:29
本文介绍了如何在同时接收具有相同 id 的多个请求时保持 API 幂等?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从我看到的很多文章和商业 API 中,大多数人通过要求客户端提供 requestId 或幂等密钥(例如 https://www.masteringmodernpayments.com/blog/idempotent-stripe-requests) 并将 requestId <-> 响应映射存储在存储中.因此,如果有一个请求已经在这个地图中,应用程序将只返回存储的响应.

From a lot of articles and commercial API I saw, most people make their APIs idempotent by asking the client to provide a requestId or idempotent-key (e.g. https://www.masteringmodernpayments.com/blog/idempotent-stripe-requests) and basically store the requestId <-> response map in the storage. So if there's a request coming in which already is in this map, the application would just return the stored response.

这对我来说都很好,但我的问题是如何处理第二个电话进来而第一个电话仍在进行中的情况?

This is all good to me but my problem is how do I handle the case where the second call coming in while the first call is still in progress?

这是我的问题

  1. 我想理想的行为是第二​​个调用一直等待直到第一个调用完成并返回第一个调用的响应?人们是这样做的吗?

  1. I guess the ideal behaviour would be the second call keep waiting until the first call finishes and returns the first call's response? Is this how people doing it?

如果是,第二个调用应该等待第一个调用完成多久?

if yes, how long should the second call wait for the first call to be finished?

如果第二次调用有等待时间限制,而第一次调用仍未完成,它应该告诉客户端什么?它是否应该不返回任何响应,以便客户端超时并重试?

if the second call has a wait time limit and the first call still hasn't finished, what should it tell the client? Should it just not return any responses so the client will timeout and retry again?

推荐答案

对于 wunderlist,我们使用数据库约束来确保没有请求 ID(它是我们每个表中的一列)被使用两次.由于我们的数据库技术 (postgres) 保证不可能插入两条违反此约束的记录,因此我们只需要正确应对潜在的插入错误.基本上,我们将此详细信息外包给我们的数据存储区.

For wunderlist we use database constraints to make sure that no request id (which is a column in every one of our tables) is ever used twice. Since our database technology (postgres) guarantees that it would be impossible for two records to be inserted that violate this constraint, we only need to react to the potential insertion error properly. Basically, we outsource this detail to our datastore.

我建议,无论您如何处理,尽量不要在您的应用程序中进行协调.如果您试图知道是否同时发生两件事,那么很可能会出现错误.取而代之的是,您可能已经使用了一个可以提供您需要的保证的系统.

I would recommend, no matter how you go about this, to try not to need to coordinate in your application. If you try to know if two things are happening at once then there is a high likelihood that there would be bugs. Instead, there might be a system you already use which can make the guarantees you need.

现在,专门解决您的三个问题:

Now, to specifically address your three questions:

  1. 对我们来说,由于我们使用数据库约束,数据库处理使事情排队等待.这就是为什么我个人更喜欢旧的 SQL 数据库——不是因为 SQL 或关系,而是因为它们非常擅长锁定和排队.我们使用 SQL 数据库作为愚蠢的断开连接的表.
  2. 这在很大程度上取决于您的系统.我们尝试将每个系统和子系统中的所有超时调整为 1 秒左右.我们宁愿快速失败也不愿排队.您可以测量并查看第 99 个百分位数的时间,如果您不知道提前将其设置为超时.
  3. 我们将向客户端返回 504 http 状态(和适当的响应正文).拥有幂等密钥的原因是客户端可以重试请求 - 所以我们从不担心超时并让他们这样做.同样,我们宁愿快速超时并解决问题,也不愿让事情排队.如果事情排长队,那么即使事情解决了,也必须等待一段时间才能好转.

这篇关于如何在同时接收具有相同 id 的多个请求时保持 API 幂等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆