检查客户端是否可以访问资源的RESTful方法是什么?

Jez*_*Jez 6 javascript rest firebug google-chrome http

我正在尝试确定REST API中的最佳实践,以确定客户端是否可以访问特定资源.两个快速示例场景:

电话目录查找服务.客户通过访问例如查找电话号码.
GET http://host/directoryEntries/numbers/12345
...在12345目录中尝试查找的电话号码在哪里.如果存在,它将返回诸如电话号码的人的姓名和地址之类的信息.

视频格式转换服务.客户端以一种格式提交视频,例如.
POST http://host/videos/
...并接收服务器为此视频生成的"视频GUID".客户然后检查例如.
GET http://host/videos/[GUID]/flv
...如果存在转换后的版本,则将视频转换为FLV格式.

您会注意到,在上述两种情况下,我都没有提到如果检查的资源存在会发生什么.这是我的问题.我在其他各个 地方读过,客户端检查资源是否存在的正确RESTful方式是调用(或可能)资源,如果资源不存在,则应该期待404响应.这很好,除了404响应被广泛认为是'错误'; 在HTTP/1.1规范规定,在4XX类的状态码适用于案件中,客户端"似乎出现了偏差".可是等等; 在这些例子中,客户肯定没有错.它期望它可以返回404(或其他;如果它没有被授权访问该资源,则可能是403),并且它在请求资源时没有任何错误.404并不是为了表示'错误条件',它只是信息 - '这不存在'. HEADGET

正如HTTP规范所暗示的那样,浏览器的行为就像404响应是真正的错误一样.每当XHR请求收到404时,Google Chrome和Firebug的控制台都会向Javascript控制台发出一条红色的"404 Not Found"错误消息,无论是否由错误处理程序处理,并且没有禁用它的方法.这对用户来说不是问题,因为他们没有看到控制台,但作为开发人员,当我完全了解时,我不希望在我的JS控制台中看到一堆404(或403等)错误以及它们不是错误,而是由我的Javascript代码处理的信息.这是线路噪音.在我给出的第二个例子中,它的线路噪声到了极端,因为客户端可能正在轮询服务器,/flv因为它可能需要一段时间来编译并且客户端想要显示"尚未编译",直到它变为非-404.每隔一两秒,JS控制台中可能会出现404错误.

那么,这是我们使用REST检查资源是否存在的最佳或最恰当的方式?我们如何绕过JS控制台中的线路噪音?可以建议,在我的第二个例子中,可以查询不同的URI来检查编译的状态,例如:
GET http://host/videos/[GUID]/compileStatus
......但是,这似乎违反了REST原则,对我而言; 你没有完全使用HTTP并注意HTTP标头,而是创建自己的协议,你在身体中返回信息告诉你你想要知道什么,并总是返回一个HTTP 200来关闭浏览器.这是对SOAP的一个主要批评 - 它试图"绕过"HTTP而不是完全使用它.根据这个原则,为什么需要返回404状态代码?您总是可以返回200 - 当然,200表示资源的状态信息可用,状态信息告诉您您真正想知道的内容 - 找不到资源.当然,RESTful方式应该是返回404状态代码.

如果我们将它应用于上面的第一个例子,这个机制似乎更加人为; 客户端可能会查询:
GET http://host/directoryEntries/numberStatuses/12345
...当然会收到200; 数字12345状态信息存在,并告诉您......在目录中找不到该号码.这意味着查询的任何数字都是"200 OK",即使它可能不存在 - 这看起来像一个好的REST接口吗?

我错过了什么吗?有没有更好的方法来确定资源是否存在RESTful,或者是否应该更新HTTP以指示非2xx状态代码不一定被视为"错误",并且只是信息?是否应该配置浏览器,以便它们不总是在JS控制台中输出非2xx状态响应作为"错误"?

PS.如果你读到这里,谢谢.;-)

jer*_*mel 2

我认为您已经更改了请求的语义。使用 RESTful 架构,您正在请求资源。因此,请求不存在或未找到的资源将被视为错误。

我用:

  • 404 如果GET http://host/directoryEntries/numbers/12345不存在。

  • 400实际上是一个错误的请求400 Bad Request

也许,就您的情况而言,您可以考虑进行搜索。搜索是通过资源集合上的查询参数完成的

你想要的是 GET http://host/directoryEntries/numbers?id=1234 它会返回 200 和一个空列表(如果不存在)或一个匹配列表。