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

RESTAPI设计:如果资源在请求的表示中不可用,则使用406或404进行响应,rest,http-response-codes,Rest,Http Response Codes,我们有一个RESTAPI从服务器获取二进制文件 请求看起来像 GET /documents/e62dd3f6-18b0-4661-92c6-51c7258f9550 HTTP/1.1 Accept: application/octet-stream 对于每一个表示错误的响应,我们想用JSON给出一个原因。 现在的问题是,由于响应的内容类型与客户端请求的内容类型不同 但是服务器应该产生什么样的响应呢 目前,它的响应是 HTTP / 1.1 406 Not Acceptable Content-T

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

请求看起来像

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"
  ...
}
这对我来说似乎是错误的,因为根本的问题是,资源不存在,而不是请求错误内容类型的客户端

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

  • 虽然请求了application/octet流,但可以用404+application/json响应吗
  • 可以用406+application/json响应吗,因为客户端没有将application/json指定为可接受的类型
  • 规范是否应该扩展,以便客户端使用q-param——例如,
    application/octet流,application/json;q=0.1
  • 其他选择
如果找不到所请求资源的表示(因为它不存在或因为服务器希望“隐藏”它的存在),服务器应该返回


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

  • 返回一个可用表示的列表。(见下文注**)
  • 只需忽略标题并返回资源的默认表示形式
请参阅文档中的以下引用,该文档定义了HTTP/1.1协议的内容和语义:

没有任何
Accept
头字段的请求意味着用户代理将接受任何媒体类型作为响应。如果请求中存在标头字段,且响应的可用表示形式中没有一种媒体类型被列为可接受,则源服务器可以通过发送
406
(不可接受)来接受标头字段响应或忽略标题字段,将响应视为不受内容协商的约束

Mozilla还提供了以下信息:

实际上,很少使用这种错误。服务器没有使用此错误代码进行响应,因为此错误代码对于最终用户来说是不明确的,并且很难修复,服务器会忽略相关的头并向用户提供实际的页面。我们假设,即使用户不会完全满意,他们也会更喜欢使用错误代码



**关于可用表示的列表,请参见此。

在完美的REST场景中,客户端将发送其理解并理解的所有表示格式。也就是说,您的浏览器通常不仅发送
Accept:text/html
,还发送一组它能理解的媒体类型(或一组不受限制的mime类型,即
image/*
*/*
)。使用限定符进行内容协商通常不是一个坏主意。因此,考虑到资源实际上不存在,服务器应该使用404响应,使用服务器选择的类型的主体,并忽略Accept标头,对吗?@GeraldMücke。是的,
404
适用于这种情况。@GeraldMücke根据您的需要,您可能需要研究:它定义简单的JSON和XML文档格式来描述HTTP API中的问题。它还定义了
application/problem+json
application/problem+xml
媒体类型。