【问题标题】:HTTP GET Request Status 204 Vs 404HTTP GET 请求状态 204 与 404
【发布时间】:2016-03-22 14:08:45
【问题描述】:

我有 2 个资源用户和相册。用户有一个专辑列表。获取专辑有 2 个 REST API。

  1. user/{userId}/albums/{albumId} 通过albumId 获取专辑。如果没有找到返回 404
  2. user/{userId}/albums 通过 userId 获取所有专辑。在这种情况下,如果用户没有相册,那么状态码 204 或 404 应该是什么?

【问题讨论】:

    标签: rest http-status-code-404 httpresponse


    【解决方案1】:

    没有专辑真的被视为错误吗?假设专辑以 JSON 数组的形式返回,对这种情况的常见响应将是 HTTP 200,其正文为空数组。

    返回 404 表示该资源不存在,这意味着甚至 不可能 请求该特定用户的专辑列表。但实际上,可以成功返回专辑列表,只是列表为空。这对我来说似乎一点也不例外。这与使用不存在的 ID(使用您的其他端点)检索特定专辑完全相反;在这种情况下,404 是正确的。

    虽然 204 似乎比 404 更好,因为它至少告诉客户端请求成功但没有内容,但它的意图并不是真正用来表示“成功缺席”。相反,它表示资源确实存在,但由于某种原因,服务器选择不将资源包含在响应正文中 - 例如,请求的目的可能只是简单地将一些标头传递回客户端。

    204 也可以用作对 POST 请求的响应,其中服务器执行了某些操作而不必创建任何新资源(这意味着 201 已创建),或者由于某些其他原因不相关返回任何资源。

    我认为很明显你需要的是一个

    GET /user/xxx/albums
    
    HTTP/1.1 200 OK
    
    []
    

    【讨论】:

    • 200 表示请求成功,响应中有数据。在这种情况下,响应中没有数据,因此 204 实际上是要返回的正确状态代码。现在,如果您调用 GET /user/xxx/albums,其中 xxx 是不存在的用户,我将返回 404 并显示未找到资源的消息。由于这是 GET,因此不会与您收到 204 POST 的典型场景混淆。归根结底,您的 API 应该有文档告诉开发人员什么状态代码对特定请求意味着什么。
    • 我不同意。有数据,一个空数组。恕我直言,强制客户端将一个完全有效的列表查询(该查询暂时为空)视为错误,这真的很奇怪,因此我们同意排除 404。但是,204 对我来说有一个特殊的用途,即客户实际上不想要或不能获得任何资源。我见过的大多数 api 都会使用一个空数组,我不明白为什么它会有任何争议。在正常的客户端编程中,您是否更喜欢 null 而不是空列表?
    • 是的,很抱歉,您回复时我正在更新我的答案。最初的评论太快了……
    • 我明白你在说什么。我想我通常选择返回 204,而不是在响应正文中返回 200,而不是返回 200。
    【解决方案2】:

    以下是定义 HTTP 协议的 RFC2616 关于状态码的说明:

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

      - 1xx: Informational - Request received, continuing process
    
      - 2xx: Success - The action was successfully received,
        understood, and accepted
    
      - 3xx: Redirection - Further action must be taken in order to
        complete the request
    
      - 4xx: Client Error - The request contains bad syntax or cannot
        be fulfilled
    
      - 5xx: Server Error - The server failed to fulfill an apparently
        valid request
    

    在您的情况下,请求成功,但没有要显示的专辑,因此您绝对应该使用 2xx 类别中的状态。

    以下是 RFC 关于 204 状态的说明:

    10.2.5 204 无内容

    服务器已完成请求,但不需要返回 实体主体,并且可能想要返回更新的元信息。这 响应可能包括新的或更新的元信息,形式为 entity-headers,如果存在应该与 请求的变体。

    如果客户端是一个用户代理,它不应该改变它的文档 从导致发送请求的角度来看。这个回应 主要是为了让行动发生的输入 不会导致用户代理的活动文档视图发生变化, 尽管应将任何新的或更新的元信息应用于 当前在用户代理的活动视图中的文档。

    204 响应不得包含消息正文,因此是 总是以标题字段后的第一个空行结束。

    RFC 声明 204 主要用于允许输入,因此您不应该使用这个。在这种情况下,我会使用 200。

    【讨论】:

    • 值得考虑的情况是,先前对所有用户相册的请求已返回内容,现在将被缓存。如果该用户的所有相册随后被删除,则返回 204 到用户相册列表的后续请求将告诉用户代理“它不应该更改导致请求被发送的文档视图” - 所以客户端的视图专辑列表不会反映空列表。
    【解决方案3】:

    错误代码 404

    当用户尝试点击损坏或死链接时,网站托管服务器通常会生成“404 Not Found”网页。

    返回码 204

    服务器已完成请求,但不需要返回实体主体。

    结论

    您显然需要返回 204 状态码。如果您使用 404 之一,用户可能会受到干扰。此外,当目标相册不存在时,您使用 404。 1 和 2 都使用 404 是不合逻辑的。

    【讨论】:

    • 该对象或空 JSON 对象 -- 如果适用 JSON。
    • 所以一个 Rest Api Endpoint 永远不会返回 404,因为路由是手动定义的? 404 只会在您使用未由您的 api 定义的 url 或在分布式系统的情况下不可用的情况下由服务器引发。
    【解决方案4】:

    当你请求一个特定的资源,比如一个用户,而该用户不存在,那么你应该返回 404。例如,你有一个 API 可以使用以下 URL 检索用户:

    https://yourdomain.com/api/users/:userid
    

    并且请求检索不存在的用户 1234,那么您应该返回 404。在这种情况下,客户端请求了一个不存在的资源。

    https://yourdomain.com/api/users/1234 
    404
    

    现在假设您有一个使用以下 url 返回系统中所有用户的 api:

    https://yourdomain.com/api/users
    

    如果系统中没有用户,那么,在这种情况下,你应该返回 204。

    【讨论】:

    • 说得好。谢谢。
    • 错了,服务器可以理解你试图访问的资源,它可以根据URI理解哪个进程,所以不应该使用404。
    【解决方案5】:

    我同意回复,但我认为是 204 或 200,这取决于您在专辑列表为空时的回复。

    如果您要返回一个空数组,则返回 200 代码,如果您不想返回任何内容,那么正确的将是 204。(我更喜欢 200 和空列表)

    仅对不存在的资源使用 404,如果是空列表则选择 204 或 200。

    好黑客!

    【讨论】:

      【解决方案6】:

      让我为此付出 2 美分。我希望您已经知道 404 与 204 之间的区别。 我更喜欢使用每个状态码的场景是:

      404 状态码

      404 表示资源未找到或不存在或 URL 无效

      例如

      GET : https://api.myapp.io/product/product_id_123
      GET : https://api.myapp.io/image/nokia.jpg
      

      如果数据库或资源文件夹中不存在单个产品/资源项,则表示此 URL 的资源无效,因此我们必须抛出 404,Google 和 bing 等搜索引擎不会缓存结果并且不会在第二天重试新内容。

      204 状态码

      204 表示 URL 有效,Server 已成功执行,但没有数据可返回。

      例如

      GET : https://api.myapp.io/product/search?keyword=nokia
      

      如果数据库中的关键字没有匹配的数据(单个或多个)返回结果,则抛出 204,因为没有数据返回但 URL 仍然有效,Google 和 bing 等搜索引擎将重试第二天再次获取新鲜内容,因为对他们来说这不是无效的 url,当您第二天重试时,可能会有一些与查询匹配的数据。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-18
        • 1970-01-01
        • 2021-04-10
        • 2013-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多