使用HTTP 204 vs 200 vs 404来安全地发信号通知资源不存在

时间:2016-02-02 09:51:26

标签: rest asp.net-web-api http-status-code-404 crud reverse-proxy

在我的REST API中,我有一些资源的普通CRUD端点。 如果我执行了GET /items/42并且没有这样的项目,那么正常的行为就是返回404 NOT FOUND

然而,有一种情况令我担忧。在这种情况下,客户端需要检查是否存在资源(由令牌隐式识别),如果不存在,则创建它。因此,客户端将尝试检索资源,如果收到404,则客户端应用程序将显示创建项目所需的UI,然后继续POST新资源。在某种程度上,这是一种特殊的资源,因为它的ID是从其他参数派生的,所以即使在创建之前它也是已知的。例如,考虑用户注册程序;客户会询问“我存在吗?如果没有 - >注册我”。

我关心的是我是否需要担心“虚假”404:s?考虑到服务器通常被API网关,反向代理等包围,是否存在由于与REST服务器本身无关的一些临时错误而导致周围实体产生404 NOT FOUND的风险?如果是这样,它可能会诱使客户相信该项目尚未创建,并且现在应该创建它。即使由于项目已经存在而导致创建项目的POST请求失败,这也不是很好,因为用户可能无缘无故地输入数据等。

这是一个需要考虑的问题还是过于偏执?我想如果客户不能相信404是幂等的(当然,在创建资源之前),还会出现许多其他问题。是否有任何实际情况,API网关或类似网站会自行报告404

如果这是一个有效的场景,我是否需要一个“更安全”,更明确的响应,说明请求已成功但未找到资源,例如使用空{JSON体'的200 OK进行响应还是{isRegistered: false}204 NO CONTENT或类似的?这为其他奇怪的事情开辟了 - 如果对不存在的资源的请求会响应200伴随着空体,那么项目的 creation 可能是{ {1}}而不是PUT等?这似乎是一堆蠕虫...这一切归结为POST是否保证给定资源不存在?”

1 个答案:

答案 0 :(得分:3)

404非常明确:资源未找到,而且是client error (4xx)。通常,服务器端错误(5xx)不会干扰并在此处产生虚假的404.

作为替代方案,如果要创建的资源以唯一方式链接到另一个资源,您可以使用OPTIONS询问服务器是否已存在。

例如:

OPTIONS /visitors/7883930/user-account

=> Allow: POST,OPTIONS(不存在)

=> Allow: GET,OPTIONS(存在)

这里的关键是拥有一个允许在不知道其ID的情况下访问资源的URI。但这并不总是可能的。