Skip to main content

3. The Problem Details JSON Object (问题详情JSON对象)

问题详情的规范模型是一个 JSON [RFC7159] 对象。

当序列化为 JSON 文档时,该格式使用 application/problem+json 媒体类型标识。

例如,携带 JSON 问题详情的 HTTP 响应:

HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
Content-Language: en

{
"type": "https://example.com/probs/out-of-credit",
"title": "You do not have enough credit.",
"detail": "Your current balance is 30, but that costs 50.",
"instance": "/account/12345/msgs/abc",
"balance": 30,
"accounts": ["/account/12345",
"/account/67890"]
}

在这里,信用额度不足问题(由其 type URI 标识)在 title 中指示了 403 的原因,通过 instance 为特定问题出现提供了引用,在 detail 中给出了出现特定的详情,并添加了两个扩展;balance 传达了账户的余额,accounts 给出了可以充值账户的链接。

传达问题特定扩展的能力允许传达多个问题。例如:

HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
Content-Language: en

{
"type": "https://example.net/validation-error",
"title": "Your request parameters didn't validate.",
"invalid-params": [ {
"name": "age",
"reason": "must be a positive integer"
},
{
"name": "color",
"reason": "must be 'green', 'red' or 'blue'"}
]
}

请注意,这要求每个子问题足够相似以使用相同的 HTTP 状态码。如果它们不相似,可以使用 207 (Multi-Status) [RFC4918] 代码来封装多个状态消息。

3.1. Members of a Problem Details Object (问题详情对象的成员)

问题详情对象可以具有以下成员:

  • type (字符串) - 标识问题类型的 URI 引用 [RFC3986]。本规范鼓励,当解引用时,它提供问题类型的人类可读文档(例如,使用 HTML [W3C.REC-html5-20141028])。当此成员不存在时,其值假定为 about:blank

  • title (字符串) - 问题类型的简短、人类可读摘要。它不应该 (SHOULD NOT) 在问题的不同出现之间改变,除非用于本地化目的(例如,使用主动内容协商;参见 [RFC7231], Section 3.4)。

  • status (数字) - 源服务器为此问题出现生成的 HTTP 状态码([RFC7231], Section 6)。

  • detail (字符串) - 特定于此问题出现的人类可读解释。

  • instance (字符串) - 标识问题的特定出现的 URI 引用。如果解引用,它可能产生也可能不产生进一步的信息。

消费者必须 (MUST) 使用 type 字符串作为问题类型的主要标识符;title 字符串是建议性的,仅包含给不知道 URI 语义且没有能力发现它们的用户(例如,离线日志分析)。消费者不应该 (SHOULD NOT) 自动解引用 type URI。

status 成员,如果存在,仅是建议性的;它为方便消费者传达了使用的 HTTP 状态码。生成器必须 (MUST) 在实际 HTTP 响应中使用相同的状态码,以确保不理解此格式的通用 HTTP 软件仍然正确行为。有关其使用的进一步注意事项,请参见第 5 节。

消费者可以使用 status 成员来确定生成器使用的原始状态码,在它已被更改的情况下(例如,由中介或缓存),以及当消息正文在没有 HTTP 信息的情况下持久化时。通用 HTTP 软件仍将使用 HTTP 状态码。

detail 成员,如果存在,应该专注于帮助客户端纠正问题,而不是给出调试信息。

消费者不应该 (SHOULD NOT) 解析 detail 成员以获取信息;扩展是获得此类信息的更合适且更不易出错的方式。

请注意,typeinstance 都接受相对 URI;这意味着它们必须相对于文档的基础 URI 进行解析,如 [RFC3986], Section 5 所述。

3.2. Extension Members (扩展成员)

问题类型定义可以 (MAY) 使用额外成员扩展问题详情对象。

例如,我们上面的"信用额度不足"问题定义了两个这样的扩展 -- balanceaccounts 来传达额外的、问题特定的信息。

消费问题详情的客户端必须 (MUST) 忽略它们不识别的任何此类扩展;这允许问题类型演化并在将来包含额外信息。

请注意,因为扩展有效地被问题类型放入命名空间中,所以在不定义新媒体类型的情况下不可能定义新的"标准"成员。