假设我有一个将用户绑定到公司的RESTful API:
PUT http://example.com/users/john.smith
{
"company": "http://example.com/companies/Nintendo"
}
但引用的公司不存在(可能是由于竞争条件,可能是由于用户错误)。操作无法成功完成,因为数据库需要外键指向现有行。什么是适当的响应代码以及为什么?
答案 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方法无关(GET
,PUT
等)。
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通常是一个永久性错误,几秒钟内无法重试。