REST API 设计:如果资源在请求的表示中不可用,则响应 406 或 404

REST API Design: Respond with 406 or 404 if a resource is not available in a requested representation

我们有一个 REST API 从服务器获取二进制文件。

请求看起来像

GET /documents/e62dd3f6-18b0-4661-92c6-51c7258f9550 HTTP/1.1
Accept: application/octet-stream

对于指示错误的每个响应,我们希望在 JSON 中给出原因。 现在的问题是,由于响应与客户端请求的内容类型不同。

但是服务器应该产生什么样的响应呢?

目前,它以

响应
HTTP / 1.1 406 Not Acceptable
Content-Type: application/json
{
  reason: "blabla"
  ...
}

这对我来说似乎是错误的,因为潜在的问题是资源不存在,而不是客户端请求错误的内容类型。

但问题是,处理这种情况的正确方法是什么?

如果没有为所请求的资源找到表示(因为它不存在或者因为服务器希望“隐藏” 它的存在),服务器应该 return 404.


如果客户端请求 Accept header 中的特定表示,而服务器无法提供此类表示,则服务器可以:

  • Return 406 以及可用表示的列表。 (见下面的注释**)
  • 简单地忽略 Accept header 和 return 资源的默认表示。

请参阅 RFC 7231 中的以下引用,该文档定义了 HTTP/1.1 协议的内容和语义:

A request without any Accept header field implies that the user agent will accept any media type in response. If the header field is present in a request and none of the available representations for the response have a media type that is listed as acceptable, the origin server can either honor the header field by sending a 406 (Not Acceptable) response or disregard the header field by treating the response as if it is not subject to content negotiation.

Mozilla 还推荐以下关于406的内容:

In practice, this error is very rarely used. Instead of responding using this error code, which would be cryptic for the end user and difficult to fix, servers ignore the relevant header and serve an actual page to the user. It is assumed that even if the user won't be completely happy, they will prefer this to an error code.


** 关于可用表示列表,请参阅此answer