我正在尝试确定 REST API 中用于确定客户端是否可以访问特定资源的最佳实践。两个简单的示例场景:
电话簿查找服务。客户端通过访问例如查找电话号码。
GET http://host/directoryEntries/numbers/12345
... 在哪里12345
是要尝试在目录中查找的电话号码。如果存在,它将返回电话号码所属人员的姓名和地址等信息。
视频格式转换服务。客户将一种格式的视频提交给例如。
POST http://host/videos/
...并接收服务器为此视频生成的“视频 GUID”。然后客户端检查例如。
GET http://host/videos/[GUID]/flv
...获取视频,转换为 FLV 格式(如果转换后的版本存在)。
您会注意到,在上面的两种情况下,我没有提到如果正在检查的资源会发生什么doesn't存在。这就是我的问题。我读过various https://stackoverflow.com/questions/1533510/rest-standard-for-get-on-a-resource-that-doesnt-exist other http://watchitlater.com/blog/2009/11/http-method-primer-for-restful-web-services/ places https://stackoverflow.com/questions/9431922/rest-standard-for-checking-if-resource-exists客户端检查资源是否存在的正确 RESTful 方法是调用HEAD
(或者可能GET
) 在资源上,如果资源不存在,则应该收到 404 响应。这没什么问题,只是 404 响应被广泛认为是“错误”;这HTTP/1.1 规范 https://www.rfc-editor.org/rfc/rfc2616声明 4xx 类状态代码适用于客户端“似乎犯了错误”的情况。可是等等;在这些例子中,客户肯定没有犯错。它expects它可能会返回 404(或其他;如果未授权访问此资源,则可能返回 403),并且在请求资源时没有犯任何错误。 404 并不是为了指示“错误情况”,它只是信息 - “该信息不存在”。
正如 HTTP 规范所建议的,浏览器的行为就像 404 响应是一个真正的错误一样。每次 XHR 请求收到 404 请求时,Google Chrome 和 Firebug 的控制台都会向 Javascript 控制台输出一条大红色的“404 Not Found”错误消息,无论它是否由错误处理程序处理,并且没有禁用它的方法。这对用户来说不是问题,因为他们看不到控制台,但作为开发人员,当我完全了解时,我不想在我的 JS 控制台中看到一堆 404(或 403 等)错误好吧,它们不是错误,而是我的 Javascript 代码正在处理的信息。这是线路噪声。在我给出的第二个示例中,线路噪声达到了极限,因为客户端可能会轮询服务器以获取该噪声/flv
因为编译可能需要一段时间,并且客户端希望显示“尚未编译”,直到得到非 404 错误。 JS控制台每隔一两秒就可能出现404错误。
那么,这是我们使用 REST 检查资源是否存在的最佳或最合适的方法吗?我们如何解决 JS 控制台中的线路噪音?很可能建议在我的第二个示例中,可以查询不同的 URI 来检查status的编译,如:
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
's 状态信息存在,并告诉您...在目录中找不到该号码。这意味着查询的任何数字都将是“200 OK”,即使它可能不存在 - 这看起来像是一个很好的 REST 接口吗?
我错过了什么吗?是否有更好的方法来确定资源是否以 REST 方式存在,或者应该更新 HTTP 以指示非 2xx 状态代码不一定被视为“错误”,而只是信息?浏览器是否应该能够进行配置,以便它们不会总是在 JS 控制台中将非 2xx 状态响应输出为“错误”?
附言。如果您读到这里,谢谢。 ;-)