有效请求但数据为空的正确REST响应代码是什么?


331

例如,您运行的GET请求,users/9但没有ID为#9的用户。哪个是最好的响应码?

  • 200 OK
  • 202接受
  • 204没有内容
  • 400错误的要求
  • 找不到404

19
提示:您找到用户9了吗?
克里斯·普佛

42
提示2:因此找不到用户9 ?
Tomasz Nurkiewicz 2012年

18
@IMB谁在说204?“无内容”表示您要查找的实体存在,但没有任何表示形式。例如,如果ID为15的博客没有评论,并且您不想为博客15的评论返回空列表:“ / blog / 15 / comments”将返回NoContent。另一方面,如果博客15确实存在,则“ 404未找到”更为合适。
克里斯·普弗

12
@Crisfole没有你的意思是“在另一方面,如果博客15也。存在,‘404未找到’更合适”
gdoron正在支持莫妮卡

15
我当然可以@gdoron!:) 谢谢。可悲的是,我要编辑和修复它已经晚了三年。
克里斯·普弗

Answers:


249

TL; DR:使用 404

请参阅此博客。它解释得很好。

博客对204以下内容的评论摘要:

  1. 204 No Content 作为浏览器的响应代码并不是非常有用(尽管根据HTTP规范,浏览器的确需要将其理解为“请勿更改视图”响应代码)。
  2. 204 No Content 但是,这可能要表示成功,而不必返回一些AJAX的Web服务是非常有用的。(特别是在案件喜欢DELETEPOSTs表示不需要反馈)。

因此,对您的问题的答案是404在您的情况下使用。204是专门的响应代码,您不应经常返回到浏览器来响应GET

其他响应代码比204和更不合适404

  1. 200应该随您成功获取的内容一起返回。当您要获取的实体不存在时,此方法不合适。
  2. 202服务器开始对某个对象进行工作但该对象尚未完全准备就绪时使用。当然这里不是这样。您尚未开始,也不会开始响应GET请求构造用户9 。这违反了各种规则。
  3. 400用于响应格式不正确的HTTP请求(例如,格式错误的http标头,顺序错误的段等)。几乎可以肯定,这将由您使用的任何框架来处理。除非您是从头开始编写自己的服务器,否则不必处理这个问题。编辑较新的RFC现在允许将400用于语义无效的请求。

Wikipedia 对HTTP状态代码描述特别有用。您还可以在www.w3.org上的HTTP / 1.1 RFC2616文档中查看定义。


8
注意:200s的响应代码表示成功。400s中的响应代码表示失败。摘要(第一点和第二点)与204响应代码(无内容)有关。
克里斯·普弗

226
-1,因为我强烈反对404作为对没有记录返回的成功调用的响应。作为处理用于非Web应用程序的API的开发人员,我浪费了很多时间与该API的开发人员联系,以追踪为什么我所调用的API端点不存在,而实际上却没有,要报告的数据。关于204对于浏览器不是特别有用,这有点像尾巴,因为我们的智能设备领域中API端点的大多数使用不是基于浏览器的,而是可能使用AJAX的。很抱歉带走点数。
马特·卡什

38
@MatthewPatrickCashatt,您可以随意随意投票。现在,我终于明白了为什么人们不赞成我,但是理由仍然是错误的。当收到404时,这并不意味着该路线没有意义,这意味着该位置没有资源。句号 如果您正在请求/badurl/user/9不存在这样的用户,则为true 。开发人员可以通过添加比“未找到”更好的原因短语来提供帮助,但这不是必需的。
克里斯·普弗

19
@Crisfole我倾向于不同意(虽然没有downvote,请继续阅读),基于关闭的404 W3的定义,具体The server has not found anything matching the Request-URI。实际上,Web /应用程序服务器已找到与请求URI匹配的ACTION,尽管db服务器未找到。但是,它也说This status code is commonly used when [...] no other response is applicable,因此我认为这可以在某种程度上验证其用法(即使我不同意/喜欢它)。
戴芬

8
我认为您没有解决我要提出的问题:404令人困惑。依靠呼叫者检查原因短语或响应的正文意味着您不信任状态码,在这种情况下,它是没有用的。
阿德里安·贝克

364

我强烈反对使用空数据的404,建议使用204或200。或至少一个应将响应实体与404一起使用。

接收到请求并对其进行了正确处理-它确实触发了服务器上的应用程序代码,因此不能真正说出这是一个客户端错误,因此整个客户端错误代码(4xx)类都不适合。

更重要的是,由于多种技术原因,可能会发生404。例如,该应用程序在服务器上被暂时停用或卸载,代理连接问题等等。因此,客户端无法区分表示“空结果集”的404和表示“找不到服务,请稍后再试”的404。

这可能是致命的:想象一下您公司中的会计服务,其中列出了所有由于年度奖金而产生的员工。不幸的是,一次调用它返回404。这是否意味着没有人要获得奖金,或者该应用程序当前已关闭以进行新的部署?

->对于关心数据质量的应用程序,没有响应实体的404因此几乎是不行的。

同样,许多客户端框架通过引发异常而没有询问其他问题来响应404。这迫使客户端开发人员捕获该异常,对其进行评估,然后基于该异常来决定是否将其记录为例如由监视组件接收到的错误或是否忽略它。对我来说那也不是很漂亮。

404与204相比,优点是它可以返回一个响应实体,该实体可能包含一些有关为何找不到所请求资源的信息。但是,如果这确实是相关的,则还可以考虑使用200 OK响应,并以允许对有效载荷数据进行错误响应的方式设计系统。或者,可以使用404响应的有效负载将结构化信息返回给调用方。如果他接收到例如可以解析的HTML页面而不是XML或JSON,那么这很好地表明了技术上的问题,而不是从呼叫者的角度来看可能是有效的“无结果”答复。或者可以为此使用HTTP响应标头。

不过,我还是更愿意使用空响应的204或200。这样,请求的技术执行状态与请求的逻辑结果是分开的。2xx表示“技术执行正常,这是结果,请处理”。

我认为在大多数情况下,应由客户决定是否可以接受空结果。通过返回404而没有响应实体,尽管有正确的技术执行,客户可以决定将情况视为简单无误的错误。

另一个快速类比:如果“ SQL查询未返回结果”,则返回404表示“未找到结果”就像抛出DatabaseConnectionException。它可以完成工作,但是有很多可能的技术原因会引发相同的异常,然后将其误认为有效的结果。


30
“未找到”的技术原因也称为服务器错误。那些应该在500年代。具体来说:“找不到服务”是503 Service Unavailable
克里斯·普弗

43
询问者还询问了一个特定的资源:一个用户(不是/users路径,而是/users/9“该用户被称为#9”),因此您的“空结果集”比较没有意义。404表示该对象不存在。
克里斯·普弗

29
404仅表示未找到请求的资源(在这种情况下为用户编号9)。它与是否触发应用程序代码无关,与后端应用程序是否响应无关。Web服务器是问题所在,问题中没有提到反向代理。
克里斯·普弗

29
这个答案的推理是错误的。
Kurt Spindler

20
404:客户端能够与给定服务器通信,但是服务器找不到请求的内容。从字面上看:收到的请求是正确且格式正确的(错误请求400),已通过身份验证或公开(未授权401 /禁止403),无需付款(需要付款402),请求方法很好(不允许使用方法405) ),则可以接受请求接受(不接受406)。当用户获取资源时,应使用200 Ok。空不是资源。400范围用于客户端错误500范围用于服务器错误简而言之:您的推理已关闭。
Derk-Jan 2016年

62

起初,我认为204是有意义的,但是在讨论之后,我相信404是唯一真正正确的答案。考虑以下数据:

用户:约翰,彼得

METHOD  URL                      STATUS  RESPONSE
GET     /users                   200     [John, Peter]
GET     /users/john              200     John
GET     /users/kyle              404     Not found
GET     /users?name=kyle`        200     []
DELETE  /users/john              204     No Content

一些背景:

  1. 搜索返回一个数组,它没有任何匹配,但是有内容:一个空数组

  2. 404当然是最著名的,所请求的服务器不支持url,但是实际上缺少的资源是相同的。
    即使/users/:name与匹配users/kyle,用户Kyle也不可用资源,因此404仍然适用。它不是搜索查询,它是动态url直接引用,所以404是。

无论如何,我的两分钱:)


9
我对REST API的这种风格投入了很多精力。除非通过调用/ users或/ users?name = kyle来告知资源将存在,否则没有客户可以要求/ users / kyle
Gary Barker

@GaryBarker但是由于这是某种形式的“用户输入”,因此API仍必须正确处理它。虽然您应该在客户端中阻止404,但不能保证实际上是首先检查了它。API的设计应在不考虑客户端的确切实现的情况下进行,尤其是在检查用户输入方面。
RicoBrassers

这是我最同意的答案。我希望API如何工作的完美示例。@GaryBarker的评论也很完美。当您通过ID查找内容时,这是一个错误,并且不存在。拨打电话之前,您应该知道ID存在。主要是因为获得一些“成功”的空响应只会使错误进一步恶化,可能是在执行user.name或其他操作时某些“无法读取未定义的属性名称”。
Jamie Twells

那两者的结合呢?假设用户有朋友。/ users / kyle / friends?name = fred。凯尔(Kyle)不存在,所以此响应为404吗?还是200,因为我们不完全关心kyle,只关心搜索名字为fred的他的朋友?
JSextonn

会产生404的IMO,因为它是无效请求:Kyle不存在,因此也无法搜索他的朋友。
Justus Romijn

23

如果期望该资源存在,但是它可能是空的,那么我认为仅用表示该事物为空的表示形式获得200 OK可能会更容易。

因此,我宁愿让/ things使用{“ Items”:[]}返回200 OK,而不返回204完全不包含任何东西,因为这样可以将具有0个项目的集合与具有一个或多个项目的集合视为相同还有更多项目。

我只剩下204个没有内容的PUT和DELETE,在这种情况下,实际上可能没有有用的表示形式。

如果/ thing / 9确实不存在,则使用404是合适的。


1
听起来您喜欢使用一种称为RPC的抽象形式针对API进行编程。customers/1/addressbookRPC方法不是像紧接动词和基于资源的url这样访问资源,而是通过调用终结点之类的方法GetCustomerAddressBook来接收数据,或者本质上是null,而不必担心HTTP的复杂性。两者都有优点和缺点。
松饼人

2
@The Muffin Man,我不确定您如何假装知道我是喜欢REST还是RPC,也不知道为什么它与关于返回HTTP GET请求的状态码的讨论有关。
j0057年

使用204时,我遇到了一些可怕的缓存问题。Chrome浏览器会奇怪地处理该请求,并且不会在网络中显示任何内容并缓存先前的结果。即使拥有世界上所有没有缓存的标头。我同意这个答案,将200个空数组/对象传递给用户似乎是最好的。
杰克

22

在以前的项目中,我使用过404。如果没有用户9,则找不到该对象。因此,404未找到是合适的。

如果存在对象,但是没有数据,则204 No Content将是适当的。我觉得你的情况,对象也没有,虽然存在。


14

根据w3的帖子,

200 OK

该请求已成功。响应返回的信息取决于请求中使用的方法

202接受

该请求已被接受进行处理,但是处理尚未完成。

204没有内容

服务器已完成请求,但不需要返回实体,可能要返回更新的元信息。

400错误的要求

由于语法格式错误,服务器无法理解该请求。客户端不应不加修改地重复请求

401未经授权

该请求需要用户认证。响应必须包含WWW-Authenticate标头字段

找不到404

服务器找不到与Request-URI匹配的任何内容。没有迹象表明这种情况是暂时的还是永久的


w3帖子是关于HTTP状态代码的。HTTP与REST不同。REST主要但不一定使用HTTP作为传输协议。404是HTTP传输错误代码。如果REST与HTTP相同,则不应该将其称为HTTP吗?
anneb

1
@anneb正如您所说的那样,REST使用HTTP,因此这个答案完全有意义。REST不是HTTP,REST也不是协议。REST不必与该答案完全相同(或与HTTP相同)即可。
Koray Tugay

@Koray Tugay:谷歌搜索也使用http,因此根据此答案,如果没有与搜索匹配的内容,谷歌搜索应响应http状态404?
anneb

@anneb您是否在Google搜索中提到了RESTful应用程序?我不这么认为。因此,答案是否定的。转向原始问题和答案,而不是陷入困境。如果Google搜索有一天创建了RESTful API(或者它已经拥有,我不知道),则204 No Content在找不到结果时可能会返回。不404,它已经为你的结果,但它没有内容..
科瑞图加伊

13

总结或简化,

2xx:可选数据:格式正确的URI:条件不是URI的一部分:如果条件是可选的,则可以在@RequestBody中指定,并且@RequestParam应该导致2xx。示例:按名称/状态过滤

4xx:期望的数据:格式不正确的URI:条件是URI的一部分:如果条件是强制性的,只能在@PathVariable中指定,则应导致4xx。示例:按唯一ID查找。

因此,对于所询问的情况:“ users / 9”应为4xx(可能为404),但对于“ users?name = superman”应为2xx(可能为204)


12

有两个问题要问。标题中一个,示例中一个。我认为,这在一定程度上导致了对哪种反应合适的争议。

问题标题询问空数据。空数据仍然是数据,但与无数据不同。所以这建议请求一个结果集,即一个列表,也许是从/users。如果列表为空,它仍然是列表,因此最适合使用204(无内容)。您刚刚询问了一个用户列表,并被提供了一个用户列表,它恰好没有任何内容。

而是提供的示例询问有关特定对象,用户, /users/9。如果找不到用户#9,则不返回用户对象。您要求提供特定的资源(用户对象),但由于没有找到该资源而没有获得资源,因此使用404是合适的。

我认为解决此问题的方法是,如果您可以按期望的方式使用响应而无需添加任何条件语句,则使用204,否则使用404。

在我的示例中,我可以遍历一个空列表,而无需检查它是否具有内容,但是我不能在不破坏某些东西或添加检查以查看其是否为空的情况下在空对象上显示用户对象数据。

如果适合您,当然可以使用null对象模式返回一个对象,但这是另一个线程的讨论。


9

看了问题之后,您不应该使用404为什么?

根据RFC 7231,正确的状态代码为204

在上面的答案中,我注意到1个小小的误解:

1.-资源是: /users

2.- /users/8不是资源,这是:/users具有route参数的资源8,消费者可能无法注意到它并且不知道差异,但是发布者知道并且必须知道这一点!...因此他必须为消费者返回准确的响应。期。

所以:

基于RFC:404错误,因为/users找到了资源,但是使用该参数执行的逻辑8未找到任何content要作为响应返回的逻辑,因此正确的答案是:204

这里的要点是:404甚至找不到资源来处理内部逻辑

204是:我找到了资源,执行了逻辑,但是我没有使用route参数中给定的条件找到任何数据,因此我无法向您返回任何信息。抱歉,请验证您的条件,然后再次致电给我。

200:好的,我找到了资源,执行了逻辑(即使当我不强制返回任何东西时)也可以随便使用它并使用它。

205:(GET响应的最佳选择)我找到了资源,执行了逻辑,为您准备了一些内容,请很好地使用,哦,如果您要在视图中共享此内容,请刷新视图显示它。

希望能帮助到你。


8

现有答案未详细说明的是,无论您使用路径参数还是查询参数,都将有所作为。

  • 对于路径参数,该参数是资源路径的一部分。如果是/users/9,则响应应该是404因为找不到该资源。/users/9是资源,结果是一元或错误,不存在。这不是单子。
  • 对于查询参数,该参数不属于资源路径。如果是/users?id=9,则响应应该是204因为/users找到了资源,但它无法返回任何数据。资源/users存在,结果为n元,即使为空也存在。如果id是唯一的,则为单子。

使用路径参数还是查询参数取决于用例。我更喜欢使用路径参数作为强制性,规范性或标识性参数,而将查询参数作为可选性,非规范性或归属性参数(例如分页,整理语言环境和内容)。在REST API中,由于可能会嵌套以获取“子记录”(如获取第一个公共ssh密钥或获取第三个邮政地址),因此我/users/9/users?id=9特别使用。/users/9/ssh-keys/0/users/9/address/2

我更喜欢使用404。这是为什么:

  • 一元(1个结果)和n元(n个结果)方法的调用不应无故改变。如果可能,我希望有相同的响应代码。预期结果的数量当然是不同的,例如,您希望主体是一个对象(一元)或对象数组(n元)。
  • 对于n元,我将返回一个数组,如果没有结果,我将不返回没有集合(无文档),我将返回一个空集合(空文档,例如JSON中的空数组或XML中的空元素)。也就是说,它仍然是200,但记录为零。除了在身体上,没有其他理由将此信息放在电线上。
  • 204就像一种void方法。我不会用它GET,只为POSTPUTDELETEGET如果标识符是查询参数而不是路径参数,我会例外。
  • 没有找到记录是喜欢NoSuchElementExceptionArrayIndexOutOfBoundsException或者类似的东西,用一个id不存在,因此,它是一个客户端错误客户端造成的。
  • 从代码的角度来看,获取204意味着可以避免代码中的另一个分支。它会使客户端代码复杂化,并且在某些情况下还会使服务器代码复杂化(取决于您使用实体/模型单子还是普通的实体/模型;我强烈建议您远离实体/模型单子,因为这可能导致讨厌的错误,因为表示您认为该操作成功了,并且当您实际上应该返回其他值时返回200或204)。
  • 客户端代码更容易编写和理解,如果2xx表示服务器执行了客户端请求的操作,而4xx表示服务器未执行客户端请求的操作,这是客户端的错误。没有向客户端提供该ID所请求的客户端是客户端的错误的记录,因为该客户端请求的ID不存在。

最后但并非最不重要的一点:一致性

  • GET /users/9
  • PUT /users/9DELETE /users/9

PUT /users/9并且在成功更新或删除的情况下DELETE /users/9已经必须返回204。那么,如果用户9不存在,他们应该返回什么?根据所使用的HTTP方法,将相同的情况显示为不同的状态代码是没有意义的。

此外,不是规范性的,而是一种文化上的原因:如果204将其用于GET /users/9项目中将要发生的下一件事是有人认为返回204对n元方法有益。这使客户端代码变得复杂,因为2xx客户端现在不仅要检查并解码主体,还必须专门检查204并在这种情况下跳过对主体的解码。芽客户该怎么办?创建一个空数组?那为什么不把它放在电线上呢?如果客户端创建空数组,则204是愚蠢压缩的一种形式。如果客户端null改为使用,则会打开一个完全不同的蠕虫罐。



3

204更合适。特别是当您具有警报系统以确保您的网站安全时,在这种情况下404会引起混乱,因为您不知道某些404警报是后端错误或正常请求,但响应为空。


如果发生后端错误,则不应返回404。
appalling22

3

我会说,两者都不是真正合适的。如前所述,例如@anneb,我也认为部分问题来自使用HTTP响应代码传输与RESTful服务相关的状态。REST服务必须说的关于其自身处理的任何内容都应通过REST专用代码进行传输。

1个

我认为,如果HTTP服务器找到了准备好响应发送请求的任何服务,则不应使用HTTP 404进行响应-最终,服务器发现了某些内容-除非服务器明确指示处理请求的服务。

让我们假设以下URL: http://example.com/service/return/test

  • 情况A是服务器“仅在文件系统上查找文件”。如果不存在,404则是正确的。如果它要求某种服务来确切地传递此文件,并且该服务告诉它不存在该名称,则情况也是如此。
  • 在情况B中,服务器不使用“真实”文件,但实际上请求是由其他服务(例如某种模板系统)处理的。在这里,服务器无法对资源的存在提出任何主张,因为它对资源一无所知(除非由处理该资源的服务告知)。

如果服务没有任何明确要求其他行为的响应,则HTTP服务器只能说三点:

  • 503 如果应该处理该请求的服务未运行或没有响应;
  • 200 否则,因为HTTP服务器实际上可以满足该请求–无论服务稍后将说什么;
  • 400404表明没有此类服务(与“存在但离线”相对),没有发现其他任何内容。

2

回到手头的问题:我认为最干净的方法是完全不使用HTTP,而不是以前说的任何响应代码。如果服务存在并且正在响应,则HTTP代码应为200。响应应在单独的标头中包含服务返回的状态–在这里,服务可以说

  • REST:EMPTY例如,是否要求搜索某物。那项研究空无一物;
  • REST:NOT FOUND是否专门问某事。“类ID” –是文件名或按ID或条目号24的资源,等等。–并且未找到特定资源(通常,已请求并未找到一个特定资源);
  • REST:INVALID 如果请求发送的任何部分未被服务识别。

(请注意,我故意在它们前面加上“ REST:”以标记一个事实,尽管它们可能具有与HTTP响应代码相同的值或措词,但它们实际上完全不同)

3

让我们回到上面的URL并检查情况B,其中服务向HTTP服务器指示它不会自行处理此请求,而是将其传递给SERVICE。HTTP只提供返回的内容SERVICE,它不知道有关该return/test部分的任何信息SERVICE。如果该服务正在运行,则HTTP应该返回,200因为它确实找到了可以处理请求的内容。

返回的状态SERVICE(如上所述,该状态希望在单独的标头中看到)取决于实际需要执行的操作:

  • 如果return/test请求特定资源:如果存在,则返回状态为REST:FOUND;如果该资源不存在,则返回REST:NOT FOUNDREST:GONE如果我们知道它曾经存在并且不会返回,并且REST:MOVED如果我们知道它已经消失了,则可以扩展为返回
  • 如果return/test认为是搜索或类似过滤器的操作:如果结果集为空,则返回请求类型的空集,状态为REST:EMPTY;一组请求类型的结果,状态为REST:SUCCESS
  • 如果return/test不是完全不正确的操作SERVICEREST:ERROR如果完全错误(例如错字retrun/test),或者REST:NOT IMPLEMENTED计划以后再返回,则返回。

4

这种区别比将两种不同的事物混合在一起要干净得多。如果有的话,这也将使调试更加容易,并且处理只会稍微复杂一些。

  • 如果返回HTTP 404,则服务器会告诉我:“我不知道您在说什么”。尽管我请求的REST部分可能还可以,但是我在所有错误的地方都在寻找par'Mach。
  • 另一方面,HTTP 200和REST:ERR告诉我我获得了服务,但是在对服务的请求中做错了什么。
  • 从HTTP 200和REST:EMPTY,我知道我没有做错任何事情-正确的服务器,服务器找到了服务,正确的服务请求-但搜索结果为空。

摘要

问题和讨论源于以下事实:HTTP响应代码用于表示其结果由HTTP进行服务的服务的状态,或表示sth。不在HTTP服务器本身的范围内。由于这种差异,问题无法得到解答,所有观点都需要进行大量讨论。

由服务而非HTTP服务器处理的请求的状态实际上不应该由HTTP响应代码给出(RFC 6919)。HTTP代码应该(RFC 2119)仅包含HTTP服务器可以从其自身范围提供的信息:即,是否找到该服务来处理请求。

取而代之的是,应该使用一种不同的方式来告知消费者关于实际正在处理请求的服务的请求状态。我的建议是通过特定的标头进行操作。理想情况下,标头名称及其内容均遵循一个标准,可使消费者轻松处理这些响应。


2

根据RFC7231-page59(https://tools.ietf.org/html/rfc7231#page-59),404状态码响应的定义为:

6.5.4。找不到404状态代码404(未找到)指示源服务器未找到目标资源的当前表示,或不愿意透露存在的一种表示形式。404状态代码不表示这种缺乏表示是暂时的还是永久的;如果原始服务器大概通过某种可配置的方式知道该条件很可能是永久性的,则与404相比,首选410(已消失)状态代码。默认情况下,404响应是可缓存的;即,除非方法定义或显式缓存控件另有说明(请参阅[RFC7234]的4.2.2节)。

引起怀疑的主要是上面上下文中的资源定义。根据同一RFC(7231),资源的定义为:

资源:HTTP请求的目标称为“资源”。HTTP不限制资源的性质;它仅定义了可用于与资源交互的接口。每个资源都由统一资源标识符(URI)标识,如[RFC7230]的2.7节所述。当客户端构造HTTP / 1.1请求消息时,它以[RFC7230] 5.3节中定义的各种格式之一发送目标URI。收到请求后,服务器将为目标资源重建有效的请求URI([RFC7230]的5.5节)。HTTP的一个设计目标是将资源标识与请求语义分开,这是通过将请求语义赋予请求方法(第4节)和一些请求修改标头字段(第5节)来实现的。

所以在我的理解中,不应在成功的GET请求中使用404状态代码,结果为空(例如:没有特定过滤器结果的列表)


2

这样的事情可能是主观的,双方都有一些有趣而多样的论据。但是[我认为] 对于缺少的数据返回404是不正确的。这里是一个简化的说明,以使这一点很清楚:

  • 请求:请问我有一些数据吗?
  • 资源(API端点):我将为您收到该请求,在此[发送对潜在数据的响应]

一切正常,找到了端点,并且找到了表和列,因此查询了数据库,并“成功”返回了数据!

现在-“成功响应”是否有数据都没有关系,您要求获得“潜在”数据的响应,并且满足了“潜在”数据的响应。空,空等是有效数据。

200只表示我们所做的任何请求都是成功的。我正在请求数据,HTTP / REST没什么问题,并且由于返回了数据(尽管为空),所以我的“数据请求”成功了。

返回200,让请求者根据每个特定情况的要求处理空数据!

考虑以下示例:

  • 请求:查询用户ID为1234的“违规”表
  • 资源(API端点):返回响应,但数据为空

此数据为空是完全有效的。这意味着用户没有违规行为。这是200,因为它全部有效,然后我可以这样做:

您没有违规行为,有蓝莓松饼!

如果您认为这是404,则说明什么?找不到用户的违规行为?现在,从语法上讲这是正确的,但是在REST世界中,关于请求的成功或失败只是不正确的。可以成功找到该用户的“违规”数据,违规为零-代表有效状态的实数。


[厚脸皮音符..]

在标题中,您下意识地同意200是正确的答案:

有效请求但数据为空的正确REST响应代码是什么?


无论主观性和棘手的选择如何,在选择使用哪种状态代码时,都需要考虑以下几点:

  1. 一致性。如果将404用作“无数据”,则每次响应不返回任何数据时使用它。
  2. 同一状态不能有多种含义。如果返回404,当资源没有被发现(如API结束点不存在等),然后不要也使用它没有返回的数据。这只会使处理响应变得很痛苦。
  3. 仔细考虑上下文。什么是“要求”?您是在说什么呢?

1

使用通用枚举对响应内容进行编码,该通用枚举允许客户端打开它并相应地分叉逻辑。我不确定您的客户如何区分“未找到数据” 404和“未找到网络资源” 404之间的区别?您不希望有人浏览到用户Z / 9并让客户端感到奇怪,好像请求是有效的,但是没有返回数据。


1

为什么不使用410?这表明所请求的资源不再存在,并且在您的情况下,期望客户端永远不要请求该资源users/9

您可以在此处找到有关410的更多详细信息:https : //www.w3.org/Protocols/rfc2616/rfc2616-sec10.html


2
“客户有望从未提出要求” -如果该用户被后来创建的,你的答案建议你能保证这个用户将永远存在,这是一个非常大胆的假设,可能是错误的东西
霍利

霍莉怎么说。补充一点:即使用户存在并被删除,410也是错误的,因为如果用户不删除该怎么办?(这是稍后创建的一种特殊情况。)
Christian Hujer,

因为410应该是永久的情况。restapitutorial.com/httpstatuscodes.html
Akostha

1

令人遗憾的是,在此线程中,如此简单且定义明确的内容成为“基于观点的”。

HTTP服务器仅知道“实体”,它是任何内容的抽象,可以是静态网页,搜索结果列表,其他实体列表,某物的json描述,媒体文件等。

期望每个这样的实体都可以通过唯一的URL来标识,例如

  • / user / 9-单个实体:USER ID = 9
  • / users-单个实体:所有用户的列表
  • /media/x.mp3-单个实体:名为x.mp3的媒体文件
  • / search-单个实体:基于查询参数的动态内容

如果服务器通过给定的URL查找资源,则其内容是什么都没关系-2G数据,null,{},[]-只要存在,它将是200。但是如果这样的实体是服务器未知,则可能返回404“未找到”。

开发人员似乎感到困惑,他们认为,如果应用程序具有针对特定路径形状的处理程序,那应该不是错误。在HTTP协议看来,只要在服务器内部没有与之匹配的实体,服务器内部发生的事件(即默认路由器是否响应还是特定路径形状的处理程序)都无关紧要。请求的URL(请求的MP3文件,网页,用户对象等),该URL将返回有效内容(空或其他),必须为404(或410等)。

另一个困惑点似乎是围绕“没有数据”和“没有实体”。前者与实体的内容有关,后者与实体的存在有关。

范例1:

  • 无数据:/ users返回200 OK,正文:[],因为尚未注册
  • 没有实体:/ users返回404,因为没有路径/ users

范例2:

  • 无数据:/ user / 9返回return 200 OK,正文:{},因为用户ID = 9从未输入过他/她的个人数据
  • 没有实体:/ user / 9返回404,因为没有用户ID = 9

范例3:

  • 无数据:/ search?name = Joe返回200 OK [],因为数据库中没有Joe
  • 没有实体:/ search?name = Joe返回404,因为没有路径/ search

0

如果您仅仅因为没有响应数据而返回,则404对于任何客户端来说都会非常混乱。

对我来说,带有空主体的响应代码200足以理解一切都完美,但没有符合要求的数据。



0

如许多人所述,404具有误导性,并且它不允许客户端区分请求uri是否不存在,或者请求的uri是否无法获取请求的资源。

预期200状态包含资源数据-因此这不是正确的选择。204状态完全意味着其他内容,不应用作GET请求的响应。

由于一个或另一个原因,所有其他现有状态都不适用。

我已经看到这个主题在多个地方一遍又一遍地讨论。对我来说,很明显,要消除围绕该主题的困惑,需要专门的成功状态。类似于“ 209-无资源可显示”。

这将是2xx状态,因为未找到ID不应被视为客户端错误(如果客户端知道服务器DB中的所有内容,他们将不需要向服务器询问任何内容,不是吗?)。这种专用身份将解决使用其他身份辩论的所有问题。

唯一的问题是:如何获得RFC接受它作为标准?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.