当前位置: 首页 > 知识库问答 >
问题:

空列表HTTP 200还是404?

南门承教
2023-03-14

我知道这是一个相当普遍的问题,但是我还没有找到让我满意的答案。

我已经使用django rest框架一段时间了,但除了给出的例子之外,这基本上是无关紧要的。其默认行为是在访问具有空项目列表的路由时返回具有空列表资源的 HTTP 200。例如:如果我们有一个路由,如/articles/来访问文章列表,但它不包含任何项目,我们将得到类似于以下json的响应:

{"count":0, "next":null, "previous":null, "items": []}

这很好。我们在/articles/找到了我们要找的资源,只是碰巧其中没有项目。

如果我们访问路由/文章/? page=1,我们会得到完全相同的响应。

目前为止,一切都好。现在我们尝试访问 /articles/?page=2,响应代码发生了变化。现在获取404,就好像找不到资源一样,并显示一条错误消息,指出该页面不包含任何结果。这与 ?page=1 的情况相同...

我对这种行为完全没问题,但今天我开始质疑这种设计。?page=1 的情况与 ?page=2 有何不同?更重要的是,在发出HEAD请求时,您如何判断请求是否“有效”?在包含任何结果的意义上有效。

这在过滤列表检查某个字段的可用性(例如,向 /users/?username=ted 发出 HEAD 请求)等情况下可能很有用。

  • 200的答复显然意味着该请求已被理解,并找到了物品
  • 404表示请求已被理解,但在该位置/URI处未找到任何项(AFAIK查询参数也是URI的一部分)
  • 如果无法理解请求,则对于语法错误将返回400,对于语义错误将返回422

这是一个好的设计吗?为什么大多数人似乎不同意它,它有什么缺点?

共有3个答案

司徒焕
2023-03-14

这实际上归结为“nullvs空集合”参数。null的情况也是HTTP 404的情况,空集合的情况也是HTTP 200的情况。

如果我们有一个像/articles/这样的路径来访问文章列表,但是它不包含任何条目

假设这是一个全球文章列表,即:

< code > http://my website/articles

那么这个响应永远不能为空,因此永远不应该是404。文章的全局列表总是存在的,因此集合总是不为空,不管它是否包含元素。

这里的一个简单示例是考虑SQL查询。如果一个表存在,即使它是空的,查询也会返回一个结果(无论它是否为空),因此使用200。如果表本身不存在,则会得到一个查询错误,因此使用404。

但是如果文章包含在另一个资源中,例如它们的作者:

< code > http://my website/authors/John doe/articles

现在我们到了< code>null(以及404)可能存在的部分。

  • 如果 johndoe 存在并且有文章,则返回一个非空列表
  • 如果 johndoe 存在并且没有文章,则返回空列表,HTTP 状态为 200
  • 如果 johndoe 不存在,则返回 null 和 HTTP 状态 404

这将正确的响应传达给用户。200显示数据已正确获取,而404显示请求的资源根本不存在。

请注意,当提到特定文章而不是列表时,这略有不同。当返回特定资源(或不返回)而不是列表时,404是“无项目”响应的唯一正确HTTP状态。

< code > http://my website/article/1

在这里,您要么返回文章,要么返回 null

< code > http://my website/authors/John doe/articles/1

在这里,当作者 johndoe 或文章 1 不存在时,您将返回 404。

锺离声
2023-03-14

这是出于UI考虑(page1必须存在!),尽管如此,它决定了响应代码。

鲁彬炳
2023-03-14

我会选择< code>200,因为资源是< code >文章。当在< code>users中查询< code>ted时,情况也是如此,< code>users是资源,只要它在那里,从我的观点来看,< code>200就可以了。如果您< code > GET < code > users/ted 一个< code>404将与一个< code>410(消失)一样好,如果一个叫ted的用户过去在那里(可能更适用于文章而不是用户)。

 类似资料:
  • 问题内容: 以下哪项将被认为是更好/更清晰/更快/更多的“ Pythonic”?我不在乎列表的内容,只关心它的持续时间。 要么 如果有什么不同,该函数也会利用。 问题答案: 一些快速的计时运行似乎使第二个选项略有优势: 只是为了好玩而已(Python v2.7.2) 我希望 首先 使用 可读代码 ,然后使用(如果可用)(例如,Python 3.x之前的版本),然后使用和。

  • 问题内容: 我在表中有一列,其中可能包含空值或空值。如何检查表中存在的行中的一列是空还是空? 问题答案: 这将选择is 或(空字符串)的所有行

  • 问题内容: 我对Redis的所有可用存储选项有些困惑。我想做一些简单的事情,我不想过度设计。我正在与和合作。 我有一个需要存储的简单关联数组。我还需要能够通过其键检索一个项目并遍历所有项目。 所以到目前为止,我一直在使用type。像这样存储我的数组: 这样,我可以像这样轻松访问密钥: 但是现在我需要遍历所有我不知道如何做的帖子,以及是否可以使用我当前的结构来完成。我不知道是否需要将所有内容存储在另

  • 本文向大家介绍MySQL判别InnoDB表是独立表空间还是共享表空间的方法详解,包括了MySQL判别InnoDB表是独立表空间还是共享表空间的方法详解的使用技巧和注意事项,需要的朋友参考一下 前言 InnoDB采用按表空间(tablespace)的方式进行存储数据, 默认配置情况下会有一个初始大小为10MB, 名字为ibdata1的文件, 该文件就是默认的表空间文件(tablespce file)

  • 问题内容: 在某处是否有标准的Google Go编码约定文档来设置制表符或空格在Go源代码中缩进是首选?如果不是,那么(统计上)更流行的选择是什么? 官方的建议是什么?(如果有) 最受欢迎的选择是什么? 问题答案: 官方建议使用以下格式格式化代码 或直接使用gofmt命令 您可以在golang.org博客上或“ 有效” go 文档中了解有关此内容的更多信息: 缩进 我们使用缩进标签,默认情况下go

  • 问题内容: 清空一个集合(在我的例子中是一个ArrayList)与创建一个新集合(并让垃圾收集器清除旧的集合)的优缺点是什么? 具体来说,我有一个叫。当发生某种情况时,我需要清空并重新填充其他内容。我应该打电话还是只做一个新的,让旧的被垃圾收集?每种方法的优缺点是什么? 问题答案: 您可以保留容器并在想减少GC的负载时调用:清空数组内的所有引用,但不使数组符合垃圾回收器的回收条件。这可能会加快将来