为什么所有的API都不一致? - Hanami


在为 Web 应用程序设计 API 时有一个特别的谜团,任何 API 专家都知道这一点,但是,并不是每个人都意识到我们的规范是多么不完整。
那就是规范中缺少的部分。
为了解释它,我需要谈谈HTTP 状态代码。
 
HTTP 状态代码
如果您曾经使用过任何 API,您就会熟悉这样一个事实,即当您向服务器发送请求时,它可以以不同的响应进行响应。
例如,如果我想获取一篇文章,服务器可以响应一个 200 状态码,包括文章内容。
但是,如果请求的资源不存在,则服务器可能会返回错误响应,并带有 404 状态代码,表明文章无法找到。
对于不同类型的响应,有许多不同的官方定义的 HTTP 代码,通常假设,

  • 成功响应从 2xx 开始,
  • 与重定向消息相关的错误响应从 3xx 开始。
  • 4xx 状态码标识用户定义输入的问题,例如缺少参数,
  • 5xx 状态代码与服务器问题有关,例如服务关闭或出现内部错误。

有一些常用的响应,如 201 或 404,但也有一些稀有的,由于规范不明确,您可能从未见过,在这种情况下它们可能有用。
一个例子是一个 300 状态码,它标识,对于某个请求,服务器可以给出不同的响应,你应该更精确。但是,没有官方指南应该在哪些特定情况下应用它或如何指定请求路径,因此很少使用这个。
 
缺失的部分
然而,即使有很多定义的状态码,也有一个普遍的问题,其中没有一个真正适用。
我的意思是,如果违反业务规则应该返回什么状态码?
这本书的例子是当你想发表一篇文章时。
假设您有一篇文章,并发布了它。如果一切顺利,您将收到来自服务器的成功响应。但是,如果您再次尝试发布文章,服务器应该如何响应并不清楚!
 
  • 禁止 (403)

解决此问题的一种方法是返回禁止错误,指示用户无法执行此操作。但是,它与用户权限无关。即使是超级管理员也不能发表已经发表的文章,因为商业规则不允许这样的事情发生!
  • 无效 (422) 或只是 BAD (400)

然后我们可以说请求无效(422)或错误(400),但如果你仔细想想,它不是!请求本身一切正常,只是在这个特定的时刻 APPLICATION 由于业务条件拒绝处理它!
  • 那么也许方法不被允许?(405)

另一个候选可能是 405 HTTP 状态代码,指的是无效方法错误。然而,这个指的是 HTTP 方法,而不仅仅是在给定时刻不可接受的动作。
同样,它指出了请求格式的问题。如果您希望您的服务器只处理 PATCH 请求并且从不接受 PUT 请求,这可能很有用,但在这种特殊情况下感觉不对。
那么还有哪些其他选择呢?
 
418:我是茶壶
嗯,有一个特别有趣的解决方案,我很想在实际应用程序中实现,即使这个解决方案也是为不同的用例设计的。这是一个teapot418 状态代码。
茶壶状态代码是在 1998 年作为愚人节玩笑发明的,正如您想象的那样,由于这个事实,它并不经常使用。
但是,应用程序有时会使用它,主要是为了防止自动查询、抓取数据或创建大量随机资源。
问题是,该服务器由于服务器已知的原因而拒绝执行某些操作 - 而不是因为用户输入已损坏或无效。
当你想发表一篇已经发表的文章时,也是同样的情况。服务器定义了内部业务规则,以防止您更改其状态。您可能会认为,418 状态代码是此用例的最佳匹配候选者!
然而,还有一个,我认为更好。
 
409 - 冲突
409,代表冲突。它指出由于请求资源的状态冲突,请求无法完成。
仅在预期用户可能能够解决冲突并重新提交请求的情况下才允许使用此代码。
在所描述的情况下,用户无法重新提交请求。文章发表了,跟请求体没什么可修复的。
然后调整表单中的电子邮件可能会使请求成功。
尽管在本示例中并非如此,但在理想的世界中,对于大多数业务违规行为,我仍会采用此方法。
但是,如果由于 OTHER 资源与其冲突而无法执行该操作怎么办?
例如,如果您想注册该用户,但 EMAIL 或 Frontend-Generated ID 已被系统中注册的 ANOTHER 用户占用,该怎么办。
 
​​​​​​​当涉及到业务逻辑违规和应用程序状态时,418 似乎是实际用例的有效候选者。