假设我有一个将用户绑定到公司的 RESTful API:
PUT http://example.com/users/john.smith
{
"company": "http://example.com/companies/Nintendo"
}
但引用的公司不存在(可能是由于竞争条件,也可能是由于用户错误)。该操作无法成功完成,因为数据库需要外键指向现有行。什么是适当的响应代码,为什么?
假设我有一个将用户绑定到公司的 RESTful API:
PUT http://example.com/users/john.smith
{
"company": "http://example.com/companies/Nintendo"
}
但引用的公司不存在(可能是由于竞争条件,也可能是由于用户错误)。该操作无法成功完成,因为数据库需要外键指向现有行。什么是适当的响应代码,为什么?
这绝对是一个4xx
错误,因为客户提供的信息是问题的根源。
由于我们正在处理语义性质的问题,HTTP 1.1 的 WebDAV422
是最适合的响应代码:
422 Unprocessable Entity (WebDAV)
422 (Unprocessable Entity)
状态码意味着服务器理解请求实体的内容类型——因此415 (Unsupported Media Type)
状态码是不合适的——并且请求实体的语法是正确的——因此400 (Bad Request)
状态码是不合适的——但无法处理包含的指令。例如,如果 XML 请求正文包含格式正确(即语法正确)但语义错误的 XML 指令,则可能会发生这种错误情况。
当然,不要让您的客户独自一人在黑暗中,并确保您在响应正文中解释错误发生的原因。
现在讨论一下为什么不是其他代码,首先是三个更令人困惑的,然后是其余的:
和其他人:
我会返回一个HTTP 400 - Bad Request
,可能会在响应正文中添加一些提示(例如,Nintendo 不是一个有效的选项)。这不是404 - Not found
错误,因为 URL 和其中引用的资源是正确的。
作为关于您的请求正文的旁注
{
"company": "http://example.com/companies/Nintendo"
}
我希望用户只传递一个名称或关于公司的 id,而不是整个 URI。你增加了更多的复杂性,却不可能获得任何东西。想象一下,一个用户在一个有错字的 URI 中传递了一个有效的公司名称,例如Sega,例如comp panies。我猜你的后端会尝试访问这个 URI,如果失败了,它会返回一个错误。好吧,你可以,但对我来说,你似乎让你和你的用户都过得很艰难。
如果服务器没有响应,您可以返回 404,如果它确实响应错误,我会返回该错误。
404 通常是一个永久性错误,在几秒钟内重试后不会消失。