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

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

问题描述

从我看到的很多文章和商业API中,大多数人通过要求客户提供requestId或idempotent-key来使其API具有幂等性(例如 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天全站免登陆