【问题标题】:HTTP status code for a partial successful request部分成功请求的 HTTP 状态代码
【发布时间】:2011-12-12 10:33:08
【问题描述】:

我有一个向用户发送消息的应用程序。在 post 请求中传输一个 XML 字符串,该字符串由应接收该特定消息的所有用户组成。如果列表中的任何用户不存在,我会将丢失用户的列表返回给客户进行进一步评估。

现在我问自己什么是正确的应用程序状态代码,表示请求已被接受,但有些事情无法完成。

如果不允许在列表中包含丢失的用户,则可以避免该问题。然后发送尝试只会得到一个 4xx 错误。但是以这种方式形成 API 是没有意义的。 另一方面,我可以认为错误条件纯粹是特定于应用程序的。但是发送 200 感觉不对。最好给客户一个提示,什么时候深入查看错误响应。例如避免一遍又一遍地向该用户发送消息

【问题讨论】:

    标签: http rest http-status-codes


    【解决方案1】:

    我处理过一个非常相似的问题。在这种情况下,我返回了一个

    207 多状态

    现在,这不是严格的 HTTP,它是 WebDAV 扩展的一部分,所以如果您也无法控制客户端,那么这对您不利。如果你这样做,你可以这样做:

       <?xml version="1.0" encoding="utf-8" ?>
       <D:multistatus xmlns:D='DAV:'>
         <D:response>
           <D:user>user-123</D:user>
           <D:status>success</D:status>
         </D:response>
         <D:response>
           <D:user>user-789</D:user>
           <D:status>failure</D:status>
         </D:response>
       </D:multistatus>
    

    但同样,这是一个 HTTP 扩展,您还需要控制客户端。

    【讨论】:

    • 我曾想过使用它,但我对它不太满意。谢谢!
    • 它的好处是您可以根据需要返回尽可能多或少的相关数据 - 这对于混合数据集特别有用,即:有些失败,有些通过。跨度>
    • 我明白了。我只是想避免额外的状态处理(恕我直言,这不是很好)。我的大部分代码都适用于 HTTP 代码。而且我认为我所描述的用例可以不用。
    • 您始终可以发回一个正文 - 发送一个带有 JSON 响应的 200 或您想要的任何内容,以确定哪些是成功的。
    • 是的,我知道。但是如果你返回一个身体,你需要解析它。在那一刻,您引入了第二层应用程序逻辑处理。这会增加复杂性,您需要有充分的理由这样做。
    【解决方案2】:

    我遇到了同样的问题,最后我使用了两种不同的解决方案:

    • HTTP 返回码202: Accepted,表示请求正常,但不能保证一切都按预期进行。
    • 在响应中返回一个正常的200,但在响应正文中包含一个未成功的列表。

    第二个通常效果最好,但如果您很懒惰或使用队列进行处理,第一个会很好。

    【讨论】:

    • 202不是更多指的是排队之类的吗?
    • 是的,@Sinaesthetic。在最新的 HTTP 1.1 规范中,“(...) 请求已被接受处理,但处理尚未完成”。因此,对于部分成功,202 合适。
    • IMO 200 明确允许部分成功,因为负载的预期含义被指定为 POST、PUT 和 DELETE 的状态。 tools.ietf.org/html/rfc7231#section-6.3.1 状态 202 是异步调用的成功启动,其结果未知。类似于获得承诺/未来。响应应该说明如何获得实际结果或至少监控状态。
    【解决方案3】:

    如何使用 206 部分内容。我知道 206 更多的是关于范围,但如果它可以指示部分成功的请求呢?

    【讨论】:

    • MDN 声明如下:“HTTP 206 Partial Content 成功状态响应码表示请求已成功,并且正文包含请求的数据范围,如要求。”据我了解,206 Partial Content 只针对具有内容范围的请求。
    • W3C RFC 文档还指定 206 用于部分完成的 GET 请求,而不是 POST。 The server has fulfilled the partial GET request for the resource. The request MUST have included a Range header field (section 14.35) indicating the desired range, and MAY have included an If-Range header field (section 14.27) to make the request conditional.w3.org/Protocols/rfc2616/rfc2616-sec10.html
    【解决方案4】:

    超文本传输​​协议处理事物的传输方面。它没有处理应用程序级错误的错误代码。

    返回 200 是正确的做法。就 HTTP 而言,请求被正确接收,处理得当,并且您正在发回响应。因此,在 HTTP 级别上一切正常。与在 http 之上运行的应用程序相关的任何错误或警告都应该在响应中。这样做还可以防止您在使用代理服务器时遇到的一些令人讨厌的问题,这些问题可能无法按您预期的方式处理某些响应。

    【讨论】:

    • HTTP 是应用层协议。您不能简单地将其放在传输和应用程序级别。如果您考虑 OSI,那么 HTTP 位于第 5-7 层。 HTTP 有点不同。大多数标头和返回代码确实是特定于应用程序的。这些代码仅取决于 HTTP 协议实体中给出的信息,而不是自定义应用程序格式的东西。关于 200,我会说如果你的定义应用于不是 POST 的动词,那么它是完全错误的。但是 POST 稍微改变了游戏规则,在这种情况下,您的假设“处理得当”也不确定
    • 严格来说,OSI 认为 HTTP 是一种应用程序级协议,当与“普通”网络服务器通信时,这是正确的。但是在您的情况下,您正在 HTTP 之上运行自己的协议,就像现在许多应用程序一样。在那种类型的使用中,HTTP 只是提供传输。 (您的应用程序正在向用户发送消息,而不是传输超文本......)
    • 只是为了清楚。 REST 方式的 HTTP 以资源为中心。在这种情况下,200 表示身份(您指定的资源),而不是指向身份方向的 3xx。使用 POST 将资源 URI 转换为处理 URI,并且需要处理错误代码。上下文发生了一些变化,事物的定义变得有点模糊或至少难以理解
    • 上下文转换也意味着没有合适的错误代码,因为该协议在设计时从未考虑到该上下文 ;-) 我还认为您应该小心使用错误代码,因为代理服务器倾向于与他们一起运行,用自定义错误页面替换您的响应,这可能是一个真正的 PITA。
    • 无论如何,感谢您回答我的问题。我刚刚发现 stackoverflow 是一个糟糕的聊天客户端 :)
    猜你喜欢
    • 2018-07-31
    • 1970-01-01
    • 2015-09-22
    • 2013-02-15
    • 2019-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    相关资源
    最近更新 更多