使用 HTTP 204 vs 200 vs 404 来安全地表示资源不存在

Use of HTTP 204 vs 200 vs 404 to safely signal that a resource doesn't exist

在我的 REST API 中,我有一些资源的正常 CRUD 端点。 如果我执行 GET /items/42 并且没有这样的项目,则正常行为将是 return 和 404 NOT FOUND

但是,有一种情况与我有关。在这种情况下,客户端需要检查资源(由令牌隐式标识)是否存在,如果不存在,则创建它。因此,客户端将尝试检索资源,如果收到 404,客户端应用程序将显示创建项目所需的 UI,然后继续 POSTing 新的资源。在某种程度上,这是一种特殊的资源,因为它的 ID 是从其他参数派生的,所以它甚至在创建之前就已经知道了。例如,考虑用户注册过程;客户会问 "Do I exist? If no -> register me".

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

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

如果这是一个有效的场景,我是否需要 "safer" 更明确的响应,说明请求肯定成功但未找到资源,例如用 200 OK 响应空 JSON 正文或 {isRegistered: false}204 NO CONTENT 或类似内容?这为其他奇怪的事情打开了大门 - 如果对不存在的资源的请求将以 200 伴随着空主体响应,那么该项目的 creation 可能会是 PUT 而不是 POST,等等?这似乎是一堆蠕虫......这一切都归结为 "Does a 404 guarantee that the given resource doesn't exist?".

404 非常明确:找不到资源,它是 client error (4xx)。通常,服务器端错误 (5xx) 不会干扰并在此处创建虚假 404。

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

例如:

OPTIONS /visitors/7883930/user-account

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

=> Allow: GET,OPTIONS(存在)

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