【问题标题】:What is the proper response status for a REST API GET returning no content?REST API GET 不返回任何内容的正确响应状态是什么?
【发布时间】:2019-03-29 10:58:29
【问题描述】:

我有一个这样的端点:

GET /api/customer/primary

如果存在主要客户,我会返回类似

{
  name: "customerName"
}

但是如果我发送 GET 并且主要客户不存在怎么办?

使用空 JSON 发送 200 OK 是否更好{}

还是只发送 204 No Content 更好?

【问题讨论】:

  • 您可能应该返回 404,因为找不到实体。
  • 我不希望客户认为发生了错误。就我而言,如果主要客户不存在,那是完全可以的。
  • 404 并不意味着发生了错误。它只是表示请求的资源不存在。否则客户端如何知道它没有资源与资源存在但它没有表示。
  • 这似乎是见仁见智。见stackoverflow.com/q/34312023/217324,双方都有争论。
  • @NathanHughes 在那个问题中讨论了不同的情况,即当实体列表被访问并且它是空的时。

标签: rest http


【解决方案1】:

404 是相应的状态码。您试图将“主要客户”表示为一种资源,但在某些情况下这种关系并不存在。这个情况就很清楚了,应该是GET请求的404。

这是一种完全可以接受的沟通方式。 404 可能会向客户端发出该资源尚不存在的信号,并且也许可以使用PUT 创建它。

204 No Content 具有特定含义,对您的情况没有多大意义。 204 不仅仅意味着不会有响应体(Content-Length: 0 可以做到这一点),但它对超媒体应用程序有更具体的应用。具体来说,它表示当用户执行导致204 的操作时,视图不应刷新。这对于例如“更新”操作是有意义的,用户可以在处理文档时偶尔保存他们的进度。与205 Reset Content 形成对比,后者表示“视图”应该重置,以便(也许)可以从头开始创建新文档。

大多数应用程序都没有走这么远。坦白说,我一个都没见过。鉴于此,用Content-Length: 0 或204 No Content 返回200 几乎是完全不相关的讨论。 HTTP 规范当然不会禁止 200 OK 和 Content-Length: 0。

这有点切线。总而言之,404 表示这个“东西”不存在,这在这里很合适。没有多重解释。有编写规范的人,有很好阅读规范的人,而在讨论的另一端有错误的人。

【讨论】:

    【解决方案2】:

    但是如果我发送 GET 并且主要客户不存在怎么办?

    使用空 JSON 发送 200 OK 是否更好{}

    还是只发送 204 No Content 更好?

    如果我对您的问题的解释正确,那么您实际上并不是在询问状态代码,而是您应该使用哪种 schema 来管理 API 中的不同情况。 p>

    对于 REST 等情况,对话的两端不一定由相同的组织和相同的发布周期控制,您可能需要考虑对话的一方使用的架构版本比另一方更新。

    那怎么可能呢?我见过的最好的处理方法集中在为扩展设计模式 - 新字段是可选的,并且已经记录了在字段不存在时应该如何理解它们的语义。

    从这个角度来看

    {}
    

    看起来不像是缺少对象的表示 - 它看起来像一个对象的表示,所有可选字段都有默认值。

    您可能想要的是 Maybe 或 Option 之类的东西 - 您不是承诺发回一个对象,而是承诺发回零个或一个对象的集合。我通常希望在 JSON 中将集合表示为 array,而不是 object。

    []
    

    现在,有了那个的想法,我认为决定您返回Maybe 的表示是合理的,其中None 的表示长度为零字节,并且Some(object) 的表示是对象的 JSON 表示。

    所以在那个设计中204 当返回None 时很有意义,并且你可以保证如果成功的响应返回一个正文,那里面确实有东西。

    这里有一个折衷 - 列表表单允许消费者始终解析数据,但即使发送了None,他们也必须这样做。另一方面,对 None 使用空表示可以节省解析,但需要消费者注意内容长度。

    因此,回顾您的两个建议,我预计使用 204 将是更成功的长期方法。

    当您想要表示没有可用对象时,另一种可能性是返回 null 原始类型。这将与 200 响应一起出现,因为内容长度将是四个字节长。

    null
    

    【讨论】:

      【解决方案3】:

      HTTP 404 状态的文本(“未找到”)是最接近情况的,但是:

      状态码的第一个数字定义了响应的类别。这 最后两位数字没有任何分类作用。有5个 第一个数字的值:

      • 1xx:信息性 - 已收到请求,继续处理
      • 2xx:成功 - 操作已成功接收, 理解并接受
      • 3xx:重定向 - 必须采取进一步措施才能将 完成请求
      • 4xx:客户端错误 - 请求包含错误语法或不能 实现
      • 5xx:服务器错误 - 服务器显然未能满足 有效的请求

      (reference)

      • 在实践中,4xx 被识别为错误,并且很可能会从网络/安全/日志基础架构发出一些警报
      • 204 语义表明服务器已成功完成请求并且没有其他内容要发送 - 不完全是发生了什么。
      • 一个常见的用例是返回 204 作为 PUT request, updating the resource 的结果。

      因此,我建议使用:

      带有空对象/数组的 HTTP 200

      就像你建议的那样。

      HTTP 200 返回一个null object,例如:

      "none"(有效的 JSON)

      或

        {
          "name": "NO_PRIMARY_CUSTOMER"
        }
      

      (这种空对象的实现取决于您对返回数据的特定系统行为)

      自定义 HTTP 2xx 代码,结果为空

      不太常见但仍然可行的替代方法是返回 2xx 范围内的自定义 HTTP 代码(例如 HTTP 230),结果为空。

      如果 API 暴露给可能使用未知工具访问/监控 API 的广泛受众,则应格外小心甚至避免使用此选项。

      【讨论】:

      • 可以使用 Cache-control 标头显式设置响应的可缓存性,因此您可以在 204 响应中设置 Cache-control: max-age=0。
      • 你是对的。缓存对 HTTP 200 也有效。删除了这一行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-12
      • 1970-01-01
      • 1970-01-01
      • 2015-10-18
      • 2021-08-16
      • 2022-10-24
      相关资源
      最近更新 更多