理解 REST 响应和 HTTP 状态码

4

我想知道在我的REST API中应该如何响应。

有效示例:

http://blah.com/api/v1/dosomething/123

上述是一个有效的请求,目前我收到了HTTP状态码200和JSON响应。
{
    "dosomething": {
        "status": "OK",
        "results": "123"
    }
}

现在我的问题是,如果传递的参数无效(我期望一个整数字符串),那么我是应该返回HTTP 200响应并在JSON响应中传回错误状态,还是应该传递类似于HTTP 400响应(坏请求),并在JSON响应中列出请求的错误/问题?

错误示例:

http://blah.com/api/v1/dosomething/123a

JSON响应:

{
    "dosomething": {
        "status": "ERROR",
        "errors": [
            "Value passed: |123a| must be a integer."
        ]
    }
}

我再次提问:当传递的参数不符合我的预期时,我应该传递200还是400 HTTP状态?还是说这个请求总是应该返回200响应码,因为它已经在工作?

什么是最佳实践?

3个回答

6
始终使用404。否则就误解了URI和资源的本质。如果http://blah.com/api/v1/dosomething/标识资源,而123a只是其参数,则其他代码可能有意义。但事实并非如此:http://blah.com/api/v1/dosomething/123标识资源。如果不存在这样的资源,则返回404 Not Found
您可能拥有某些实现细节,可以处理http://blah.com/api/v1/dosomething/123http://blah.com/api/v1/dosomething/123a两个资源,但它不是资源。根据Roy Fielding的dissertation:
"资源不是存储对象。资源也不是服务器用来处理存储对象的机制。资源是一个概念映射——服务器接收标识符(用于标识映射),并将其应用于当前的映射实现(通常是集合特定的深度树遍历和/或哈希表)以找到当前负责的处理程序实现,然后处理程序实现根据请求内容选择适当的操作+响应。所有这些特定于实现的问题都隐藏在Web界面背后;客户端只能通过Web界面访问,不能假设它们的本质。"

如果使用了错误的域名(例如我意外地在生产环境中使用了qual服务器)怎么办?或者是api/v2/dosomething/123?或者是api/v1/dosomethingwrong/123?或者是API网关/ CDN上的404配置错误,没有将请求转发到源?或者是指向错误主机的错误DNS记录?从实际应用程序代码返回404会使所有这些问题都变得非常麻烦。并不是说我不同意这是正确的“REST”答案,只是REST中的错误处理是一种分层违规。 - Adrian Baker

4
作者已编辑:422是错误答案。我误解了最初的问题并给出了无效的答案,请查看@fumanchu的回复:https://dev59.com/e2TWa4cB1Zd3GeqPGcG4#10955717。下面是我的错误答案。 我建议使用“422 Unprocessable Entity”,并在响应正文中包含失败信息。

422(无法处理的实体)状态码表示服务器理解请求实体的内容类型(因此,415(不支持的媒体类型)状态码是不适当的),并且请求实体的语法正确(因此,400(错误请求)状态码是不适当的),但是无法处理包含的指令。例如,如果XML请求正文包含形式良好(即语法上正确但语义上有误的)XML指令,则可能出现此错误条件。

在处理错误时,使用“200 OK”或任何其他状态代码是不可接受的。
附注: 状态代码列表: http://www.iana.org/assignments/http-status-codes/http-status-codes.xml

那么回应的正确HTTP状态是存在的。我使用1.0或1.1 HTTP协议版本是否重要? - Phill Pafford
1
Phil:这并不重要,但在这种情况下,422根本不是正确的响应。首先,在此请求中没有有效载荷(请求实体)。 (尽管在许多其他情况下,422是正确的响应) - Julian Reschke
@Julian,您说得完全正确,我误解了最初的问题。422状态码并不是正确的使用方式,我假设您正在执行写入操作。 - ioseb
如果有人遇到类似但不完全相同的问题,因为您的回答包含有用信息,因此会给您点赞。此外,您还指出这是错误答案并进行了更新,很好。 :) - lagweezle

-2

HTTP 400用于表示HTTP请求本身存在问题(例如无效的HTTP头)。虽然您没有收到预期的参数,但请求仍然是有效的HTTP请求,因此我建议返回200响应,但在您的JSON中包含缺少参数的详细信息。


这是一个常见的误解。400 是客户端应用程序错误,因此它可以代表整个失败案例范围。最新的 Httpbis 规范更改了 400 错误的措辞,以显示它可以更广泛地应用 http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-19#section-7.4.1。 - Darrel Miller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接