【发布时间】:2023-04-06 04:27:01
【问题描述】:
我正在尝试确定 REST API 中的最佳实践,以确定客户端是否可以访问特定资源。两个简单的示例场景:
电话目录查找服务。客户通过访问 eg.GET http://host/directoryEntries/numbers/12345
查找电话号码
...其中12345 是要尝试在目录中查找的电话号码。如果存在,它将返回电话号码所在的人的姓名和地址等信息。
视频格式转换服务。客户将一种格式的视频提交给 eg.POST http://host/videos/
...并接收服务器为此视频生成的“视频 GUID”。客户端然后检查例如。GET http://host/videos/[GUID]/flv
... 获取视频,转换为 FLV 格式,如果转换后的版本存在。
您会注意到,在上述两种情况下,我没有提到如果正在检查的资源 不存在 会发生什么。这是我的问题。我在variousotherplaces中读到,客户端检查资源是否存在于此处的正确RESTful方法是调用资源上的HEAD(或者可能是GET),如果资源不存在,它应该期待 404 响应。这很好,除了 404 响应被广泛认为是“错误”; HTTP/1.1 spec 声明 4xx 类状态代码适用于客户端“似乎出错”的情况。可是等等;在这些例子中,客户肯定没有犯错。 预计它可能会返回一个 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 来检查编译的状态,例如: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 接口吗?
我错过了什么吗?是否有更好的方法来确定资源是否存在 RESTfully,或者是否应该更新 HTTP 以指示非 2xx 状态代码不一定被视为“错误”,而只是信息?浏览器是否应该能够进行配置,以便它们不会总是在 JS 控制台中将非 2xx 状态响应输出为“错误”?
PS。如果你读到这里,谢谢。 ;-)
【问题讨论】:
标签: javascript http rest google-chrome firebug