制作更好的 HTTP API

2025-06-10

制作更好的 HTTP API

过去几年,我一直在使用各种 HTTP API。这些 API 通常不对外公开,​​仅供合作伙伴公司使用。此外,我也见过其他开发者开发的 API,并且亲自参与过一些 API 的开发。这些 API 通常存在设计缺陷,这使得使用这些 API 进行可靠的集成变得更加困难。

我讨论的问题是出现错误时重复创建资源。当资源创建与支付等关键的现实操作相关时,这一点至关重要。

Paypal 的创建付款 API为例:当您创建新的付款资源(通过向 /v1/payments/payment 发出 POST 请求)时,PayPal 会立即向用户扣款。如果交易成功,您会收到状态码 201 Created 以及付款 ID。这意味着,如果您在发送此请求时遇到网络问题,由于您不知道付款 ID,因此无法轻松判断付款是否成功。更糟糕的是,如果您在网络错误时自动重试,那么您无疑会在某个时候向用户收取两次费用。

当然,这是 API 的一个已知问题,PayPal 也提供了解决方案。请参阅如何避免重复付款?您可以使用标头 PayPal-Request-Id(虽然 Payments API 页面上没有记录),也可以滥用发票号码来删除重复请求。但解决方案真的需要这么复杂吗?这两种方法都不太方便用户:消费者需要一种可靠的机制来生成请求 ID,以便重复的请求具有相同的请求 ID;在第二种情况下,如果您需要支持一张发票进行多笔付款,该怎么办?或许有更优雅的解决方案。

使用 POST/PUT 资源创建解决重复资源创建问题

如果 POST 请求只进行数据库录入和资源 ID 生成,则可以轻松避免此问题。流程如下:

POST/PUT 资源创建

使用此流程,当网络故障发生时,可以轻松重试请求。如果重试 POST 请求,只会导致重复的空资源。如果重试 PUT 请求,则不会发生问题,因为 PUT 请求是幂等的

我发现 POST/PUT 的创建模式更加优雅,尽管它需要两次请求才能完整地创建一个资源。你可能不喜欢这种方法,但我的观点是,如果 POST 请求在实际应用中会导致严重的后果,你应该支持某种方法来消除重复的 POST 请求。如果你不提供这样的机制,你的 API 很难实现稳定可靠的集成。

感谢阅读,希望对您有所帮助。欢迎关注我的 Twitter,分享您在使用 API 时遇到的问题以及解决方法。

鏂囩珷鏉ユ簮锛�https://dev.to/orkon/making-better-http-apis-72l
PREV
使用 Zod 和 TypeScript 在 Express.js 中验证请求数据:综合指南
NEXT
如何利用 DEV 建立 DEV 关系 谁在 DEV 上?在 DEV 上做什么 #devrel 标签