我知道这是一个相当常见的问题,但我找不到满足我的答案。
我现在已经使用django rest框架了一段时间,但除了给出的示例之外,这几乎是无关紧要的。它的默认行为是在访问具有空列表项的路由时返回带有空列表资源的HTTP 200。
例如:如果我们有/articles/
这样的路线来访问文章列表但它不包含任何项目我们会得到如下json的响应:
{"count":0, "next":null, "previous":null, "items": []}
哪个非常好。我们在/ articles /中找到了我们要查找的资源,它恰好没有任何项目。
如果我们访问路线/articles/?page=1
,我们会得到完全相同的回复。
到目前为止一切顺利。现在我们尝试访问/articles/?page=2
,响应代码也会发生变化。现在得到一个404
,就好像找不到资源一样,错误消息说该页面没有结果。与?page = 1 ...
我对这种行为非常满意,但今天我开始质疑这个设计。 ?page=1
案例与?page=2
的情况有何不同?还有什么,你怎么知道这个请求是否有效"何时发出HEAD请求?在包含任何结果的意义上是有效的。
这在过滤列表检查特定字段的可用性(例如向HEAD
发出/users/?username=ted
请求)的情况下非常有用。
这是一个好设计吗?为什么大多数人似乎不同意它并且有什么缺点?
答案 0 :(得分:11)
我会选择200
因为资源是articles
。
虽然ted
中的users
查询同样适用,但users
是资源,只要它存在,我200
就可以了。
如果您GET
users/ted
404
,那么410 (GONE)
与dhcp-uris-3626:foundation johndcowan$ sass --watch
ruby(3631,0x7fff7d721300) malloc: *** error for object 0x7faac2801808: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
一样好,如果过去有一个名为ted的用户(可能更适用于文章而不是用户)。
答案 1 :(得分:3)
这是由UI考虑因素驱动的(第1页必须存在!),然而,它决定了响应代码。
答案 2 :(得分:0)
200只表示请求已成功。响应返回的信息取决于请求中使用的方法,例如: GET在响应中发送与所请求资源相对应的实体;
HEAD对应于所请求资源的实体标题字段在响应中发送,没有任何消息体;
POST一个描述或包含行动结果的实体;
跟踪包含终端服务器收到的请求消息的实体。 404 - 服务器没有找到与Request-URI匹配的任何内容 - 在这种情况下,我认为这意味着我们没有找到列出文章的页面。 那就是200。 - 但也许可以理解返回的内容并格式化已经返回0篇文章的消息。
答案 3 :(得分:0)
这实际上归结为“null
vs 空集合”论点。 null
的情况也是 HTTP 404 的情况,空集合的情况也是 HTTP 200 的情况。
如果我们有一个诸如 /articles/ 之类的路由来访问文章列表但它不包含任何项目
假设这是一个全局的文章列表,即:
<块引用>http://mywebsite/articles
那么这个响应永远不能为空,因此永远不应该是 404。文章的全局列表总是存在的,因此集合总是非空的,无论它是否包含元素。
这里的一个简单示例是考虑 SQL 查询。如果表存在,即使是空的,查询也会返回结果(无论是否为空),所以使用200。如果表本身不存在,你会得到一个查询错误,所以404。< /p>
但是如果文章包含在另一个资源中,例如他们的作者:
<块引用>http://mywebsite/authors/johndoe/articles
现在我们进入了 null
(因此 404)可能有意义的部分。
null
和 HTTP 状态 404这会向用户传达正确的响应。 200 表明数据被正确获取,而 404 表明所请求的资源根本不存在。
请注意,在引用特定文章而不是列表时,这略有不同。当返回特定资源(或不返回)而不是列表时,404 是“无项目”响应的唯一正确 HTTP 状态。
<块引用>http://mywebsite/article/1
在这里,您要么返回文章,要么返回null
。
http://mywebsite/authors/johndoe/articles/1
在这里,当 作者 johndoe 或文章 1 不存在时,您将返回 404。