是否应该将未实现的可选、静态定义的资源定义为 403 或 501(或其他)?

Should an optional, statically-defined resource that is unimplemented be defined as 403 or 501 (or something else)?

我有一个设备,我正在为其实施 HTTP API 并通过 OpenAPI 3.0 对其进行定义。 定义了以下路径:

/scan/inventory/start
/scan/location/start
/scan/direction/start

此 API 设计用于在各种设备上 运行,但并非所有设备都实现了 locationdirection 功能,但都实现了 inventory 特征。可以通过获取 /scan 路径来查询可用的功能。

对于不支持 location 的设备,如果有人尝试使用它,我的团队一直在纠结 return 的错误代码。我们希望在发生这种情况时提供有用的反馈,因此 404 似乎被排除在外,特别是因为该路径记录在我们的 API 中。在反复阅读 RFC-7231 及其各种摘要后,501 或 403 似乎是不错的选择。

起初,“501 Not Implemented”似乎是个不错的选择,但 5XX class 的错误似乎表明存在更严重的服务器错误。

由于我们想提供反馈,“403 Forbidden”似乎不错,并且让客户端承担访问错误路径的责任。

我确定问题的一部分是我们正在尝试使用不一定为任意 APIs 设计的规范 (HTTP)。

你建议我们做什么?

这是一个非常简单的 404

The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

403 是不对的,因为这表明用户未被“授权”访问该资源。这意味着问题出在客户端。但在这种情况下,根本就没有资源。

501 是不对的,因为“表示服务器不支持满足请求所需的功能。当服务器无法识别请求方法并且不支持时,这是适当的响应能够为任何资源支持它。”在这种情况下,服务器支持请求没有问题,只是资源不存在。

请注意,“服务器”是指 Web 服务器。问题不在于您的应用程序作为一个整体是否支持某些功能,而在于 Web 服务器是否能够处理它发送的 HTTP 请求。使用 HTTP 状态代码来指示那种高级应用程序状态是不合适的。

另请注意,状态代码不仅仅是您的应用程序与其用户之间的私人合同。 Web 堆栈中的所有参与者(记录器、中间缓存、浏览器等)可能会根据状态代码更改其行为。这就是为什么为实际的服务器错误保留 5xx 之类的东西很重要。

总而言之,由于该 URI 处的资源不存在,因此提供有用反馈的最佳方式是 return 404。如果您想区分该设备从不支持的功能和根本不支持的功能,您应该使用状态代码以外的机制。幸运的是,您在 /scan.

列出了可用的功能,这是一个良好的开端