请求实体中断链接的响应是什么?

时间:2013-05-19 06:53:25

标签: rest

假设我有一个将用户绑定到公司的RESTful API:

PUT http://example.com/users/john.smith

{
  "company": "http://example.com/companies/Nintendo"
}

但引用的公司不存在(可能是由于竞争条件,可能是由于用户错误)。操作无法成功完成,因为数据库需要外键指向现有行。什么是适当的响应代码以及为什么?

3 个答案:

答案 0 :(得分:2)

这肯定是4xx错误,因为客户提供的信息是问题的根源。

由于我们正在处理语义性质的问题,HTTP 1.1's WebDAV 422是最合适的响应代码:

  

<强> 422 Unprocessable Entity (WebDAV)

     

422 (Unprocessable Entity)状态代码表示服务器理解请求实体的内容类型 - 因此415 (Unsupported Media Type)状态代码不合适 - 以及语法< / strong>请求实体正确 - 因此400 (Bad Request)状态代码不合适 - 但无法处理包含的指令。例如,如果XML请求主体包含格式正确(即语法正确)但语义错误的XML指令,则可能会出现此错误情况。

当然,不要让您的客户孤身一人,并确保您在回复正文中解释为什么错误发生。


现在讨论为什么不是其他代码,首先是三个更令人困惑,然后是其他代码:

  • 400 Bad Request由于语法格式错误,服务器无法理解该请求。客户端不应该在没有修改的情况下重复请求。 - 语法正常(请求格式正确)。错误是语义的(公司不存在)。此外,客户端可以在其他时间(添加公司之后)重复请求而不进行修改,并且它可能会起作用。所以,不是400。

  • 403 Forbidden 服务器理解请求,但拒绝履行请求。授权无效,请求不应重复:这通常在客户端经过身份验证但缺少对请求的资源的许可(写入,读取或其他要求)时发出。不是403。

  • 404 Not Found 服务器未找到与Request-URI 匹配的任何内容:请注意,错误与 Request-URI 有关,即用户。当用户(URI中的那个)不存在时,应该发送此响应,而不是公司。
  • 其他人:

  •  401 Unauthorized 请求需要用户身份验证:无需在此进行争论。
  •  402 Payment Required 此代码保留供将来使用:此处均未提供。
  • 405 Method Not Allowed:与HTTP方法无关(GETPUT等)。
  • 406 Not Acceptable:这与接受标头有关。
  • 407 Proxy Authentication Required:与代理相关。
  • 408 Request Timeout:显然不是。
  • 409 Conflict由于与资源的当前状态发生冲突,无法完成请求。服务器中当前(之前保存的)资源(用户的公司)正常。任何新公司都是可以接受的,新公司和现有公司之间不会发生冲突,因为新公司总是会覆盖当前公司。
  • 410 Gone服务器上不再提供所请求的资源,并且不知道转发地址。与此无关。
  • 411 Length Required:这是Content-Length标题。
  • 412 Precondition Failed:关于request-header字段。
  • 413 Request Entity Too Large:与实体的大小无关。
  • 414 Request-URI Too Long:也不是URI的大小。
  • 415 Unsupported Media Type:请求中的实体正常(服务器知道JSON)。
  • 416 Requested Range Not Satisfiable:关于Range请求标头。
  • 417 Expectation Failed:关于Expect请求标头。
  • 423 Locked (WebDAV) 423(已锁定)状态代码表示方法的源或目标资源已锁定:此处未锁定任何内容。
  • 424 Failed Dependency (WebDAV) 424(失败的依赖关系)状态代码表示无法对资源执行该方法,因为请求的操作依赖于另一个操作而该操作失败:没有任何操作链在目前的背景下。
  • 答案 1 :(得分:1)

    我会返回HTTP 400 - Bad Request,可能会在响应正文中添加一些提示(例如Nintendo不是有效选项)。这不是404 - Not found错误,因为其中引用的URL和资源是正确的。

    作为关于请求正文的旁注

    {
      "company": "http://example.com/companies/Nintendo"
    }
    

    我希望用户只传递一个名称或公司的id,而不是整个URI。你增加了更多的复杂性而不可能获得任何东西想象一下,用户传递有效的公司名称,例如 Sega ,在具有拼写错误的URI中,例如排版 P anies 。我猜你的后端会尝试访问这个URI,如果失败了,它会返回一个错误。好吧,你可以,但对我而言,你似乎正在使你和你的用户生活困难。

    答案 2 :(得分:0)

    如果服务器没有响应,您可以返回404,如果它确实响应错误,我将返回该错误。

    404通常是一个永久性错误,几秒钟内无法重试。

    http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html