【问题标题】:should http status codes be used in REST API designREST API 设计中是否应该使用 http 状态码
【发布时间】:2014-06-24 06:34:59
【问题描述】:

例如,与 SOAP 相比,http REST 的优势之一是 REST 利用机器语言/约定来传达很多含义(即 http POST 表示创建,http DELETE 表示删除......等)。 . 所以它消除了与所有协议(如肥皂)的免费相关的许多歧义和错误空间..

也就是说,我想知道是否需要将该概念扩展到 http 响应类型.. 特别是在涉及错误时.. 所以假设我收到了这个 api 调用,我想在其中获取可用驱动程序的数量我:

get api/drivers

如果找到一些驱动程序..那么通常你会返回带有驱动程序数量 + 详细信息等的 json。但是当找到 0 个驱动程序时会发生什么?您应该以与 0 相同的格式返回数据吗?还是应该使用 http 响应代码并返回 http 404 代码?

虽然使用 404 代码与约定优于配置的想法是一致的.. 并且让机器语言完成大部分解释/解释.. 我发现一些工程师抱怨 404 响应更像是抛出异常, 就好像出了什么问题,当用户附近有 0 个可用驱动程序是完全正常的。

更新

在查找附近司机/餐馆等数量的情况下。答案可能很明显。但是当您创建一个做出假设的休息 api 时会发生什么......例如这个

get api/drivers/eta

这意味着获取最近的驱动程序的 eta。如果周围没有 个驱动​​程序会发生什么?在这里使用 404 或返回正常的 200 并在 json 正文中解释不存在驱动程序会更有意义吗?

【问题讨论】:

  • 什么是“最近司机的 eta”?
  • 最近司机的预计到达时间

标签: api http rest soap


【解决方案1】:

对集合资源的GET 请求可以返回一个空集合。此响应为200 OK,因为(空)集合存在。返回 404 Not Found 意味着 no 集合存在,但事实并非如此。

请求:

GET /restaurants

回复:

200 OK
Content-Type: application/json

{
  "count": 0,
  "restaurants": []
}

【讨论】:

  • ok.. 如果您想在周围没有司机的情况下将 eta 送到最近的司机那里怎么办?查看更新的问题
【解决方案2】:

我在Build APIs You Won't Hate 的端点理论一章中介绍了这一点,但我可以简要介绍一下。

...假设我收到了这个 api 调用,我想在其中获取我周围可用驱动程序的数量:

获取 api/驱动程序

Weeeeell 它不是“在你身边”,除非你传递一些坐标,因为它是无状态的,我们不希望一些随机后台逻辑跟踪用户位置。保持这种状态会很困难而且很奇怪,所以让我们根据要求传递它。

GET /api/drivers?lat=X&lon=Y

如果找到一些餐厅..那么通常你会返回带有餐厅数量+详细信息等的 json。但是当找到 0 个餐厅时会发生什么?您应该以与 0 相同的格式返回数据吗?还是应该使用 http 响应代码并返回 http 404 代码?

我们从司机跳到这里的餐馆,这让我有点困惑,但要回答更普遍的问题:空集合是 404?

不!集合是一种资源(哇!),一种存在的实际事物。如果你有一袋扳手,那么这个袋子就是一种资源,就像扳手是一种资源一样。与我一起?

所以,你有这个扳手包。你把所有的扳手都借出去了,但你还有包。或者,也许您刚拿到包,但还没有扳手到。或者也许有人问你是否有紫色扳手。

所有这些请求都将返回一个空的扳手袋。

基本上,GET /restaurants 应该始终为 200 OK,直到您弃用并从 API 中删除餐厅概念的那一天。如果没有餐馆,那没关系,你有一个空的餐馆数组。

当你创建一个做出假设的 rest api 时会发生什么......例如这个

获取 api/drivers/eta

这意味着获取最近的驱动程序的 eta .. 如果周围没有驱动程序会发生什么?在这里使用 404 或返回正常的 200 并在 json 正文中解释不存在驱动程序会更有意义吗?

这将是你的 REST API 中的一个 rando-RPC 端点,所以从那里开始吧。

如果您有一个希望看到驱动程序进展的特定顺序,那么您不需要这个任意的 RPC 样式端点。你可以做的是:

GET /apis/orders/<uuid>

这很容易在几分钟内就有一个“eta”字段,但我认为另一个端点可以改善这一点:

GET /apis/orders/<uuid>/updates

此列表将在厨房完成准备时更新,在司机上车时更新,在司机半路时更新,在司机停车时更新,等等。

同样,如果有 没有 个更新,那只是一个空的更新包。

【讨论】:

  • 嘿@Phil Sturgeon 我试图购买“电子书”,但它告诉我有运费..这是一个api错误吗? ?
  • 这太奇怪了!看起来您找到了解决方法,并且订单已被接受并履行。我会在你的电子邮件上给你发个错误,看看我们是否能弄清楚为什么会发生这种情况,因为它绝对不应该。 :)
  • 我订购了这本书..得到了确认..但没有书!现在我该怎么做? ?
  • 我有包含指向您的链接的电子邮件记录,但我认为您使用的地址可能不正确。请发送电子邮件至 phil@apisyouwonthate.com,我会手动将您的下载链接发送给您。 ?
  • 好的,让我们通过电子邮件讨论这个问题......这里越来越乱了?
【解决方案3】:

在设计解决方案时,请考虑以下几点:易用性、简单的实施和维护。

关于 HTTP 错误代码:虽然它比定义您自己的代码有优势,但使用它可能会干扰正常的 HTTP 错误,从而限制您将来使用这些日志的选择,例如质量分析、入侵检测......

然后调用方必须处理和区分 HTTP 错误代码和应用程​​序/api 错误代码。因此,如果您收到 500,这将是由于某些未捕获的错误而导致的内部服务器错误,还是有人因为错过了一些强制性参数而将其解雇。如果您收到 404,这是因为您错过了输入您的 URI(或 URL 已更改),或者因为服务器没有找到您请求的某些数据,例如在上面的例子中“找不到出租车”

查看一些实现的 api,例如 Google api、FB..它们在返回的回复中定义了返回码(无论是 json/xml/text...)

【讨论】:

    【解决方案4】:

    首先,/api/drivers/eta 不代表服务器上的资源。我们试图将其建模为不是 RESTful 设计的资源;但是让我们假设您的业务需要支持这样的端点。当在服务器上找不到由 URL 标识的资源时,应使用 404。所以在这种情况下,带有空响应的 200 OK 更有意义。或者,如果您希望将其视为错误情况,您可以在响应负载中使用 422 或 400 以及适当的消息

    请求:

    GET /api/drivers/eta

    回复:

    200 正常 内容类型:application/json

    { “计数”:0, “司机”:[] }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      • 2014-02-08
      • 1970-01-01
      • 2020-09-07
      相关资源
      最近更新 更多