【问题标题】:HTTP status while POST with incorrect data (using id of resource which does not exist)POST 时数据不正确时的 HTTP 状态(使用不存在的资源 ID)
【发布时间】:2018-11-11 14:00:15
【问题描述】:

当我执行 POST 请求以创建新用户时,要返回的正确 HTTP 状态是什么,但其中一个参数不正确 - 我在用户数据中包含的公司 ID数据库中不存在。

发布 数据:{用户名:'newuser',年龄:99,company_id:34}

数据库中不存在 id 为 34 的公司。

我在想是否可以:

  • 400,一种无效数据,但有效但不存在id
  • 404 - 但不清楚哪个资源不存在
  • 409,因为这是一种冲突,用户可以通过更改公司 ID 来解决此问题
  • 422?
  • 或 500 - 因为这是一种数据库错误,而不允许存在不存在的 id

【问题讨论】:

    标签: rest http-status-codes http-status-code-422


    【解决方案1】:

    400422

    首先,请记住它是client error,所以5xx 状态码不适合这里。然后你应该选择一个4xx 状态码。

    最明显的选项是400422

    • 如果 JSON 语法无效,则返回 400
    • 如果 JSON 语法有效但其内容无效,则返回422,表示服务器无法处理请求实体。

    请参阅RFC 4918 中的以下引用(对于您的情况,当它说 XML 时,请阅读 JSON):

    11.2. 422 Unprocessable Entity

    422(不可处理实体)状态码表示服务器 理解请求实体的内容类型(因此 415(不支持的媒体类型)状态码不合适),并且 请求实体的语法是正确的(因此是 400 (Bad Request) 状态码不合适)但无法处理包含的 指示。例如,如果 XML 请求正文包含格式正确(即语法正确),但是 语义错误的 XML 指令。

    answer 解决了类似的情况。


    例如,如果负载的内容包含无效值(但在语法上有效),GitHub API v3 也会返回 422

    在 API 调用中存在三种可能的客户端错误类型 接收请求正文:

    1. 发送无效的 JSON 将导致 400 Bad Request 响应。 [...]

    2. 发送错误类型的 JSON 值将导致 400 Bad Request response。 [...]

    3. 发送无效字段将导致422 Unprocessable Entity 响应。 [...]


    Michael Kropatset of diagrams 放在一起,在选择最合适的状态代码时非常有见地。 4xx 状态码见下图:

    【讨论】:

    • 连接到WebDAV的这个状态怎么样?我在某处看到只有在支持 WebDAV 功能时才应该使用它。
    • @AgataAndrzejewska 某处在哪里? WebDAV 是一个 HTTP 扩展,422 是一个有效的 HTTP 状态码 registered in IANA
    • 我通常建议人们避免使用与 WebDAV 相关的状态代码,除非他们积极使用 WebDAV 标准作为其 API 的基础;我认为消费者会从一个晦涩的标准中挑选一个特定的(尽管是适当的)状态代码而忽略有关该标准的所有其他内容,这会让消费者感到困惑。 en.wikipedia.org/wiki/Principle_of_least_astonishment
    • CassioMazzochiMolin,我在这篇文章中读过:keycdn.com/support/422-unprocessable-entity
    • @PaulTurner 我在考虑简单性和清晰度以及 400 的描述“公司 ID 无效/不正确”。该请求似乎没有无效的语法问题。一般来说,我描述的 POST 请求似乎并不罕见,我没有看到 API 中返回很多 422 错误。
    【解决方案2】:

    404 Not Found 是返回 POST 请求的有问题的状态。这意味着您发送请求的资源不存在;调用者的 URL 错误。

    最明显(和通用)的答案是:400 Bad Request

    这只是表明您的请求有问题(错误在于调用者而不是服务器),然后在您的响应正文中表达出问题的具体细节。这通常是处理请求验证的方式。


    理想的答案是通过向他们所属的公司发送请求来添加用户:

    POST /company/34
    Content-Type: application/json
    {
        "username": "newuser",
        "age": 99
    }
    

    这意味着调用者必须找到一个有效的company 资源才能将请求发送到。如果company/34 不存在,则404 Not Found 响应是合适的;您尝试将用户添加到不存在的公司。

    这确实意味着您的 API 必须使用资源语义进行结构化,并且用户必须完全属于一家公司。

    【讨论】:

    • 我会选择422,如我的answer 中所述。
    【解决方案3】:

    这里,这张图很不错,我用过很多次了。

    Which code should I return?

    我会选择 404。资源可能存在(不是格式错误)但它不存在(因此无法找到)。

    【讨论】:

    • 谢谢,根据这张图我应该用422。
    • 404 在这里没有意义。
    • @CassioMazzochiMolin 您是否介意尝试添加一些有用的东西而不是无意义地抨击,比如为什么我的推理是错误的?
    猜你喜欢
    • 2014-01-22
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 2018-10-21
    • 2017-03-23
    相关资源
    最近更新 更多