rest - 当资源不存在时,从休息服务返回什么?

标签 rest restful-url

我知道关于这个主题有很多类似的帖子,但仍然没有一个能够解决我对这个问题的疑虑。所以,我会尝试恢复当前的场景。在本例中,我围绕 3 个资源对 Web 服务进行了建模(我只对获取资源感兴趣):

  • 请求列表:与 /requests 形式的 URL 关联(带有用于过滤的可选查询字符串参数);
  • 单个请求:通过 /requests/{id} 形式的 URL 进行标识
  • 单独查询:始终与请求相关联,并且仅在请求达到特定内部状态(例如:已关闭)后才存在。在本例中,网址的格式为 /requests/{id}/inquiry

场景 1

现在,对于资源 1(请求列表),即使没有针对指定过滤器的请求,Web 服务也将始终返回 200。例如,假设这个请求:

GET /requests?location=London&priority=1

即使没有来自伦敦的具有该优先级的请求,也会返回 200

200 OK


[]

我这样做是因为资源确实存在(在本例中,资源列表存在并由 url /requests 标识),但没有一个与当前查询兼容。在这种情况下,使用空列表返回 200 似乎是一个好主意,但我不确定这是否与 RFC 3986 兼容,RFC 3986 表示完整的 URL (/requests?location=London&priority=1) 是资源标识符。既然如此,那就意味着这里可以/应该使用 404。在我看来,返回 200 并带有空列表是正确的方法,但我希望得到一些反馈。

场景 2

获取单独的请求(资源 2)似乎更简单,在这里我认为当有人请求不存在的请求时(例如:/requests/100),404 是理所当然的。并且没有使用该 ID 的请求)。大家觉得怎么样?

场景 3

这有点复杂。好的,我首先将查询建模为资源,该资源由 URL /requests/{id}/inquiry 标识。查询始终与特定请求相关联(这就是为什么我使用前面的 URL 来获取查询),但它只会在内部请求对象之后创建(该对象也作为资源公开,如场景 2 所示)达到预定状态。我对该服务的最初实现遵循了场景 2 中提出的相同想法:如果没有查询,则返回 404;如果响应正文中包含查询数据,则返回 200。

现在,在这种情况下,我对我最初的实现有一些疑问。例如,如果请求存在,但它仍未达到创建查询的预定义状态,我是否应该返回 204 no content ?毕竟请求是有效的,查询的路径也是正确的。我最初的 react 是否定的,因为查询被建模为资源(因此,由于它是单个项目而不是场景 1 中的集合,因此返回的正确 HTTP 代码应该是 404)。但是,存在对请求的依赖性,如果请求存在,那么创建查询只是时间问题。大家觉得怎么样?

顺便说一句,我还有最后一个问题:有人问我如何区分来自错误网址的 404 错误和来自不存在资源的 404 错误。对我来说,它们是相同的(即,即使一个可能没有击中服务器,而另一个击中服务器并且没有任何可返回的内容),但我可以看到在客户端上获取该信息的值(value)(例如:由于错误而获得无效的网址可能会导致记录,这可能有助于更快地修复问题)。我知道我可以在请求正文中发送一些带有额外信息的信息,但是当客户想要自动处理它时,这不会有太大帮助。

最佳答案

What to return from a rest service when a resource does not exist?

如果服务器发送响应来传达资源没有当前表示,那么我们将使用 404 状态代码,给出通用 HTTP组件对响应的粗略理解,并指示某些语义(例如:我们可以缓存此响应以供以后重用吗?)

REST 和 HTTP 都为您提供了很大的自由度来决定您的资源何时没有当前表示。

例如,决定您的资源始终具有当前表示是完全合理的。例如,您可以设计您的资源,以便它们具有默认表示,当您的服务器有其他信息时,该表示会被修改。

返回一个空列表作为资源的表示就是这个想法的一个例子。

但它不一定是一个列表;它可以是一个列表。如果您考虑一下我们在现实世界中有时被要求填写的纸质表格,它们通常是从一个模板开始的,其中有一堆数据字段留空。我们可以自由地对网络资源做同样的事情。在最极端的情况下,"template"本身就是一个空文档;没关系。

(这样做是否符合人体工程学取决于您的用例;HTTP 和 REST 为您提供了自由,以便您可以在有意义的情况下这样做。弄清楚您是否有这样的情况这对你来说很有意义。)


Returning 200 with an empty list in this case does seem like a good idea, but I'm not really sure if this is compatible with RFC 3986, which says that the complete URL (/requests?location=London&priority=1) is a resource identifier.

这是个好主意,您可以做到。返回空列表与 RFC 3986 没有任何冲突。

Getting an individual request (resource 2) seems to be simpler and here I think that 404 is simply a no brainer when someone asks for a non-existing request

这不是“理所当然”的事情;您应该考虑返回默认表示是否是更好的方法。但返回 404 是正确选择的情况很常见。

should I return 204 no content instead?

通常不会;如果您想要传达查询资源确实具有当前表示形式,并且该表示形式的长度为零字节,那么您应该返回内容长度为 0 的 200。

I've been asked how to differentiate between 404 from a bad url vs a 404 from non-existing resource.... I know that I can send some info back on the body of the request with extra information, but that won't help much when clients want to process it automatically. Any ideas here?

帮不了你太多 - 使用响应正文通常是正确的答案。想想网络上的情况:当我们想告诉人们出现了问题时,我们将这些详细信息包含在 HTML 正文中。

对于 API,您可能需要考虑 Problem Details .

关于问题细节的一个有趣的事情:它定义了 type其值是标识问题类型的 URI 值的成员。

在 HTTP 中,我们还有 Link Headers ,它提供了一种描述 anchor URI 和目标 URI 之间关系的机制。因此,如果您有合适的链接关系,那么您可以将问题详细信息中的类型提升到 HTTP header 中。

IANA link relations registry包含指向每个已注册关系的引用的链接,因此您可以浏览该列表以查看是否已注册了任何合适的内容。如果做不到这一点,您可以定义自己的 extension relation .

因此,可能可以使用链接关系 header 来提供客户端“自动”处理响应所需的功能(取决于其他因素,您认为什么是“自动”)。

关于rest - 当资源不存在时,从休息服务返回什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75800739/

相关文章:

java - 使用@Consumes、@Produces 和 JAXB 的简单 JAX-RS 示例

REST 服务设计 : cancel an order?

java - 安全灰熊 HttpServer (HTTPS)

api - Swagger 集成到 Dropwizard 中

iphone - AFNetworking POST 到 REST Web 服务

嵌套对象的 RESTful 重新排序

asp.net-mvc - 如何保护 MVC RESTful Urls 免受黑客攻击?

java - restful web 服务 : HTTP Status 500. 服务器遇到内部错误,阻止它完成此请求错误

java - Restful Web 服务出错

用于从子资源列表中更新/添加/删除项目的 REST 设计