RFC 9457 HTTP API 的问题详情 2023 年 7 月
Nottingham 等 标准跟踪 [页]
流:
互联网工程任务组 (IETF)
RFC:
9457
废止:
7807
类别:
标准跟踪
发布:
ISSN:
2070-1721
作者:
M. Nottingham
E. Wilde
S. Dalal

RFC 9457

HTTP API 的问题详情

摘要

本文档定义了一种“问题详情”,用于在 HTTP 响应内容中承载机器可读的错误详情, 以避免为 HTTP API 定义新的错误响应格式。

本文档废止 RFC 7807。

本备忘录状态

这是一份互联网标准跟踪文档。

本文档是互联网工程任务组 (IETF) 的成果。它代表了 IETF 社群的共识。它已经 接受公开审查,并已由互联网工程指导组 (IESG) 批准发布。关于互联网标准的更多 信息可见 RFC 7841 第 2 节。

关于本文档当前状态、任何勘误以及 如何提供反馈的信息,可在 https://www.rfc-editor.org/info/rfc9457 获取。

目录

1. 引言

HTTP 状态码([HTTP] 的第 15 节)并不总是能够传达足够有用的错误信息。虽然使用 Web 浏览器的人通常能够理解 HTML [HTML5] 响应内容, 但 HTTP API 的非人类消费者很难这样做。

为解决这一不足,本规范定义了简单的 JSON [JSON] 和 XML [XML] 文档格式,用于描述所遇到问题的具体情况 ——“问题详情”。

例如,考虑一个响应,指出客户端的账户没有足够的余额。API 的设计者可能决定使用 403 Forbidden 状态码,以告知通用 HTTP 软件(如客户端库、缓存和代理)该响应的一般语义。 API 特定的问题详情(例如服务器拒绝该请求的原因以及适用的账户余额) 可以承载在响应内容中,以便客户端能够适当地采取行动(例如, 触发向账户转入更多余额)。

本规范用 URI [URI] 标识具体的“问题类型”(例如“余额不足”)。HTTP API 可以使用其控制下的 URI 来标识它们专有的问题,也可以复用既有 URI 以促进互操作性 并利用共同语义(见第 4.2 节)。

问题详情可以包含其他信息,例如一个用于标识该问题具体发生实例的 URI (实际上是为“上周四 Joe 没有足够余额的那次”这一概念提供标识符), 这可用于支持或取证目的。

问题详情的数据模型是一个 JSON [JSON] 对象;当序列化为 JSON 文档时,它使用 "application/problem+json" 媒体类型。附录 B 定义了一种等价的 XML 格式,它使用 "application/problem+xml" 媒体类型。

当它们在 HTTP 响应中传达时,问题详情的内容可以使用 主动协商来协商;见 [HTTP] 的第 12.1 节。 特别是,人类可读字符串所使用的语言(例如 title 和 description 中的字符串) 可以使用 Accept-Language 请求头字段([HTTP] 的第 12.5.4 节)协商, 尽管这种协商仍可能导致返回非首选的默认表示。

问题详情可以与任何 HTTP 状态码一起使用,但它们最自然地适配 4xx 和 5xx 响应的语义。请注意,问题详情(自然地)并不是在 HTTP 中传达 问题详情的唯一方式。例如,如果响应仍然是某个资源的表示, 通常更适合用该应用自身的格式来描述相关详情。同样,已定义的 HTTP 状态码覆盖了许多场景,无需传达额外详情。

本规范的目标是为需要通用错误格式的应用定义这种格式, 使它们不必定义自己的格式,或者更糟糕地,被诱使重新定义 现有 HTTP 状态码的语义。即使某个应用选择不使用它来传达错误, 审视其设计也可以帮助指导在既有格式中传达错误时所面对的设计决策。

有关相对于 [RFC7807] 的更改列表,见附录 D

2. 需求语言

本文档中的关键词 "MUST"、"MUST NOT"、 "REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、 "RECOMMENDED"、"NOT RECOMMENDED"、 "MAY" 和 "OPTIONAL", 只有在它们像这里所示那样以全大写形式出现时,才应按 BCP 14 [RFC2119] [RFC8174] 中的描述解释。

3. 问题详情 JSON 对象

问题详情的规范模型是一个 JSON [JSON] 对象。当序列化在 JSON 文档中时,该格式由 "application/problem+json" 媒体类型标识。

例如:

POST /purchase HTTP/1.1
Host: store.example.com
Content-Type: application/json
Accept: application/json, application/problem+json

{
  "item": 123456,
  "quantity": 2
}
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 标识)在 "title" 中指出 403 的原因,用 "instance" 标识该问题的具体发生实例,在 "detail" 中给出 针对此发生实例的详情,并添加了两个扩展:"balance" 传达账户余额,"accounts" 列出可以为账户充值的链接。

在经过相应设计时,特定于问题的扩展可以传达同一问题类型的多个 实例。例如:

POST /details HTTP/1.1
Host: account.example.com
Accept: application/json

{
  "age": 42.3,
  "profile": {
    "color": "yellow"
  }
}
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
Content-Language: en

{
 "type": "https://example.net/validation-error",
 "title": "Your request is not valid.",
 "errors": [
             {
               "detail": "must be a positive integer",
               "pointer": "#/age"
             },
             {
               "detail": "must be 'green', 'red' or 'blue'",
               "pointer": "#/profile/color"
             }
          ]
}

这里虚构的问题类型定义了 "errors" 扩展,它是一个数组, 描述每个验证错误的详情。每个成员都是一个对象,包含用于描述问题的 "detail", 以及用于通过 JSON Pointer [JSON-POINTER] 定位请求内容中问题位置的 "pointer"。

当 API 遇到多个不共享同一类型的问题时,RECOMMENDED 在响应中表示最相关或最紧急的问题。 虽然可以创建通用的“批处理”问题类型来传达多个不同类型的问题, 但它们并不能很好地映射到 HTTP 语义。

还要注意,即使客户端没有在 Accept 中列出 "application/problem+json" 类型,API 也以该类型作出了响应, 这是 HTTP 允许的(见 [HTTP] 的第 12.5.1 节)。

3.1. 问题详情对象的成员

问题详情对象可以具有以下成员。如果成员的值类型 与指定类型不匹配,则该成员MUST 被忽略—— 即处理将继续进行,就像该成员不存在一样。

3.1.1. "type"

"type" 成员是一个 JSON 字符串,包含一个 URI 引用 [URI],用于标识问题 类型。消费者MUST 使用 "type" URI(必要时在解析后) 作为问题类型的主要标识符。

当该成员不存在时,其值假定为 "about:blank"。

如果类型 URI 是定位器(例如带有 "http" 或 "https" scheme 的那些),解引用它SHOULD 提供该问题类型的 人类可读文档(例如,使用 HTML [HTML5])。但是,消费者SHOULD NOT 自动解引用该类型 URI,除非它们是在向开发者 提供信息时这样做(例如,在使用调试工具时)。

当 "type" 包含相对 URI 时,它会按照 [URI] 第 5 节 相对于文档的基 URI 解析。然而,使用相对 URI 可能造成混淆, 并且它们可能不会被所有实现正确处理。

例如,如果两个资源 "https://api.example.org/foo/bar/123" 和 "https://api.example.org/widget/456" 都 响应一个等于相对 URI 引用 "example-problem" 的 "type", 则在解析后它们将标识不同的资源 (分别为 "https://api.example.org/foo/bar/example-problem" 和 "https://api.example.org/widget/example-problem")。因此,RECOMMENDED 在可能时在 "type" 中使用绝对 URI,并且在使用相对 URI 时, 应包含完整路径(例如 "/types/123")。

类型 URI 允许是不可解析 URI。例如, tag URI scheme [TAG] 可用于 唯一标识问题类型:

tag:example@example.org,2021-09-17:OutOfLuck

不过,本规范鼓励使用可解析的类型 URI, 因为将来可能会需要解析该 URI。例如,如果某个 API 设计者使用了上面的 URI,后来又采用了一个会解析类型 URI 以发现错误相关信息的工具,那么要利用该能力就需要 切换到可解析 URI,从而为该问题类型创建新的身份,并因此 引入破坏性更改。

3.1.2. "status"

"status" 成员是一个 JSON number,表示源服务器为该问题发生实例 生成的 HTTP 状态码([HTTP] 第 15 节)。

"status" 成员如果存在,只是建议性的; 它传达用于方便消费者的 HTTP 状态码。生成者MUST 在实际 HTTP 响应中使用相同的状态码, 以确保不理解这种格式的通用 HTTP 软件仍然能够正确运行。 有关其使用的进一步注意事项,见第 5 节

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

3.1.3. "title"

"title" 成员是一个 JSON 字符串,包含对问题类型的简短、 人类可读摘要。

SHOULD NOT 随同一问题从一次发生 到另一次发生而变化,除非是为了本地化(例如使用主动内容协商; 见 [HTTP] 第 12.1 节)。

"title" 字符串是建议性的,仅为不了解并且无法发现 type URI 语义的用户而包含(例如,在离线日志分析期间)。

3.1.4. "detail"

"detail" 成员是一个 JSON 字符串,包含针对此问题发生实例的 人类可读解释。

"detail" 字符串如果存在,应当着重帮助客户端纠正问题, 而不是提供调试信息。

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

3.1.5. "instance"

"instance" 成员是一个 JSON 字符串,包含一个 URI 引用, 用于标识问题的具体发生实例。

当 "instance" URI 可被解引用时,可以从中获取问题详情 对象。它也可能通过使用主动内容协商,以其他格式返回关于问题发生实例的信息 (见 [HTTP] 第 12.5.1 节)。

当 "instance" URI 不可被解引用时,它充当该问题发生实例的 唯一标识符;该标识符可能对服务器具有意义,但对客户端是不透明的。

当 "instance" 包含相对 URI 时,它会按照 [URI] 第 5 节 相对于文档的基 URI 解析。然而,使用相对 URI 可能造成混淆, 并且它们可能不会被所有实现正确处理。

例如,如果两个资源 "https://api.example.org/foo/bar/123" 和 "https://api.example.org/widget/456" 都 响应一个等于相对 URI 引用 "example-instance" 的 "instance", 则在解析后它们将标识不同的资源 (分别为 "https://api.example.org/foo/bar/example-instance" 和 "https://api.example.org/widget/example-instance")。因此,RECOMMENDED 在可能时在 "instance" 中使用绝对 URI,并且在使用相对 URI 时, 应包含完整路径(例如 "/instances/123")。

3.2. 扩展成员

问题类型定义MAY 使用特定于该问题类型的 其他成员来扩展问题详情对象。

例如,上面的余额不足问题定义了两个这样的扩展—— "balance" 和 "accounts",用于传达额外的、特定于问题的信息。

类似地,“验证错误”示例定义了一个 "errors" 扩展, 它包含一个列表,列出发现的各个错误发生实例,并带有详情以及指向 每个错误位置的指针。

消费问题详情的客户端MUST 忽略任何 不识别的此类扩展;这允许问题类型演进并在未来包含额外信息。

创建扩展时,问题类型作者应谨慎选择其名称。 为了可用于 XML 格式(见附录 B),它们需要符合 [XML] 的第 2.3 节中的 Name 规则。

4. 定义新的问题类型

当 HTTP API 需要定义一个表示错误条件的响应时, 通过定义新的问题类型来做到这一点可能是适当的。

在这样做之前,重要的是要理解它们适合做什么, 以及哪些内容最好留给其他机制处理。

问题详情不是底层实现的调试工具;相反,它们是一种暴露 HTTP 接口本身更多细节的方式。新问题类型的设计者需要仔细考虑 安全考虑事项第 5 节,特别是通过错误消息暴露实现内部细节 从而暴露攻击向量的风险。

同样,真正通用的问题——即可能适用于 Web 上任何资源的条件—— 通常最好表达为普通状态码。例如,“不允许写访问”问题可能是不必要的, 因为对 PUT 请求响应 403 Forbidden 状态码已经是不言自明的。

最后,应用可能有更适合的方式在其已经定义的格式中承载错误。 问题详情旨在避免必须建立新的“故障”或“错误”文档格式, 而不是替代现有的特定领域格式。

尽管如此,可以使用 HTTP 内容协商为既有 HTTP API 添加对 问题详情的支持(例如,使用 Accept 请求头来表示对此格式的偏好; 见 [HTTP] 第 12.5.1 节)。

新的问题类型定义MUST 记录:

  1. 一个类型 URI(通常带有 "http" 或 "https" scheme)
  2. 一个适当地描述它的标题(考虑简短)
  3. 要与其一起使用的 HTTP 状态码

问题类型定义MAY 指定在适当情况下使用 Retry-After 响应头([HTTP] 第 10.2.3 节)。

问题类型 URI SHOULD 解析为 HTML [HTML5] 文档,该文档解释如何解决该 问题。

问题类型定义MAY 指定问题详情对象上的额外成员。 例如,扩展可以使用类型化链接 [WEB-LINKING] 指向机器可用来解决问题的另一个资源。

如果定义了这类额外成员,它们的名称SHOULD 以字母开头(ALPHA,如 [ABNF] 附录 B.1 所述),并且SHOULD 由 ALPHA、DIGIT ([ABNF] 附录 B.1)和 "_" 组成(以便它可以序列化为 JSON 以外的格式),并且它们 SHOULD 至少为三个字符。

4.1. 示例

例如,如果你正在为在线购物车发布 HTTP API, 你可能需要指出用户余额不足(上面的示例),因此无法完成购买。

如果你已经有能够容纳这些信息的应用特定格式, 那么最好使用它。但是,如果没有,你可以使用一种问题详情格式——如果你的 API 基于 JSON,则使用 JSON;如果它使用 XML,则使用 XML。

为此,你可以在注册表(第 4.2 节)中查找是否已有适合你目的的 已定义 type URI。如果有可用的,你可以复用该 URI。

如果没有可用的,你可以铸造并记录一个新的 type URI (该 URI 应当受你控制并且随时间保持稳定)、一个适当的标题以及将与之一起使用的 HTTP 状态码,并说明它的含义以及应如何处理。

4.2. 已注册的问题类型

本规范定义了“HTTP Problem Types”注册表, 用于常见、广泛使用的问题类型 URI,以促进复用。

该注册表的策略是 Specification Required,按 [RFC8126] 第 4.6 节

在评估请求时,指定专家应考虑社区反馈、该问题类型定义得有多好, 以及本规范的要求。供应商特定、应用特定和部署特定的值不能被注册。 规范文档应以稳定、免费可得的方式发布 (理想情况下位于某个 URL),但不必是标准。

注册MAY 对 type URI 使用前缀 "https://iana.org/assignments/http-problem-types#"。 请注意,这些 URI 可能无法被解析。

注册请求应使用以下模板:

类型 URI:
[该问题类型的 URI]
标题:
[该问题类型的简短描述]
推荐的 HTTP 状态码:
[最适合与该类型一起使用的状态码]
参考:
[指向定义该类型的规范]

有关注册请求发送位置的详细信息,见 <https://iana.org/assignments/http-problem-types> 处的注册表。

4.2.1. about:blank

本规范注册一个 Problem Type,即 "about:blank", 如下所示。

类型 URI:
about:blank
标题:
见 HTTP 状态码
推荐的 HTTP 状态码:
N/A
参考:
RFC 9457

当 "about:blank" URI [ABOUT] 用作问题类型时,表示该问题除了 HTTP 状态码的语义之外没有额外语义。

使用 "about:blank" 时,title SHOULD 与该代码推荐的 HTTP 状态短语相同 (例如,404 对应 "Not Found",依此类推),不过它MAY 被本地化以适应客户端偏好(通过 Accept-Language 请求头表达)。

请注意,根据 "type" 成员的定义方式(第 3.1 节),"about:blank" URI 是该成员的默认值。因此,任何没有携带显式 "type" 成员的问题详情对象 都隐式使用该 URI。

5. 安全考虑事项

定义新的问题类型时,必须仔细审查所包含的信息。 同样,在实际生成问题时——无论它如何序列化——也必须审查所给出的详情。

风险包括泄露可被利用来破坏系统、访问系统或损害 系统用户隐私的信息。

鼓励提供发生实例信息链接的生成者避免通过 HTTP 接口提供 实现细节,例如堆栈转储,因为这可能暴露服务器实现及其数据等的敏感细节。

"status" 成员复制了 HTTP 状态码本身可用的信息, 因而带来了二者不一致的可能性。它们的相对优先级并不明确, 因为不一致可能表示(例如)中介在传输过程中更改了 HTTP 状态码 (例如通过代理或缓存)。通用 HTTP 软件(如代理、负载均衡器、防火墙 和病毒扫描器)不太可能知道或尊重该成员中传达的状态码。

6. IANA 考虑事项

在“Media Types”注册表下的“application”注册表中,IANA 已更新 "application/problem+json" 和 "application/problem+xml" 注册,使其引用本文档。

IANA 已按照第 4.2 节中的规定创建“HTTP Problem Types”注册表, 并按照第 4.2.1 节填入 "about:blank"。

7. 参考文献

7.1. 规范性参考文献

[ABNF]
Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, , <https://www.rfc-editor.org/info/rfc5234>.
[HTTP]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/info/rfc9110>.
[JSON]
Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC8126]
Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, , <https://www.rfc-editor.org/info/rfc8126>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[URI]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[XML]
Bray, T., Paoli, J., Sperberg-McQueen, C. M., Maler, E., and F. Yergeau, "Extensible Markup Language (XML) 1.0 (Fifth Edition)", W3C Recommendation REC-xml-20081126, , <https://www.w3.org/TR/2008/REC-xml-20081126/>.

7.2. 资料性参考文献

[ABOUT]
Moonesamy, S., Ed., "The "about" URI Scheme", RFC 6694, DOI 10.17487/RFC6694, , <https://www.rfc-editor.org/info/rfc6694>.
[HTML5]
WHATWG, "HTML: 现行标准", <https://html.spec.whatwg.org>.
[ISO-19757-2]
ISO, "Information technology -- Document Schema Definition Language (DSDL) -- Part 2: Regular-grammar-based validation -- RELAX NG", ISO/IEC 19757-2:2008, , <https://www.iso.org/standard/52348.html>.
[JSON-POINTER]
Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., "JavaScript Object Notation (JSON) Pointer", RFC 6901, DOI 10.17487/RFC6901, , <https://www.rfc-editor.org/info/rfc6901>.
[JSON-SCHEMA]
Wright, A., Ed., Andrews, H., Ed., Hutton, B., Ed., and G. Dennis, "JSON Schema: A Media Type for Describing JSON Documents", Work in Progress, Internet-Draft, draft-bhutton-json-schema-01, , <https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-01>.
[RDFA]
Adida, B., Birbeck, M., McCarron, S., and I. Herman, "RDFa Core 1.1 - Third Edition", W3C Recommendation, , <https://www.w3.org/TR/2015/REC-rdfa-core-20150317/>.
[RFC7807]
Nottingham, M. and E. Wilde, "Problem Details for HTTP APIs", RFC 7807, DOI 10.17487/RFC7807, , <https://www.rfc-editor.org/info/rfc7807>.
[TAG]
Kindberg, T. and S. Hawke, "The 'tag' URI Scheme", RFC 4151, DOI 10.17487/RFC4151, , <https://www.rfc-editor.org/info/rfc4151>.
[WEB-LINKING]
Nottingham, M., "Web Linking", RFC 8288, DOI 10.17487/RFC8288, , <https://www.rfc-editor.org/info/rfc8288>.
[XSLT]
Clark, J., Pieters, S., and H. Thompson, "Associating Style Sheets with XML documents 1.0 (Second Edition)", W3C Recommendation, , <https://www.w3.org/TR/2010/REC-xml-stylesheet-20101028/>.

附录 A. HTTP 问题的 JSON Schema

本节给出一个用于 HTTP 问题详情的非规范性 JSON Schema [JSON-SCHEMA]。 如果它与规范正文之间存在任何不一致,则以后者为准。

# NOTE: '\' line wrapping per RFC 8792
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "An RFC 7807 problem object",
  "type": "object",
  "properties": {
    "type": {
      "type": "string",
      "format": "uri-reference",
      "description": "A URI reference that identifies the \
problem type."
    },
    "title": {
      "type": "string",
      "description": "A short, human-readable summary of the \
problem type."
    },
    "status": {
      "type": "integer",
      "description": "The HTTP status code \
generated by the origin server for this occurrence of the problem.",
      "minimum": 100,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "A human-readable explanation specific to \
this occurrence of the problem."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "A URI reference that identifies the \
specific occurrence of the problem. It may or may not yield \
further information if dereferenced."
    }
  }
}

附录 B. HTTP 问题与 XML

使用 XML [XML] 的 基于 HTTP 的 API 可以使用本附录中定义的格式来表达问题详情。

XML 格式的 RELAX NG schema [ISO-19757-2] 如下:

   default namespace ns = "urn:ietf:rfc:7807"

   start = problem

   problem =
     element problem {
       (  element  type            { xsd:anyURI }?
        & element  title           { xsd:string }?
        & element  detail          { xsd:string }?
        & element  status          { xsd:positiveInteger }?
        & element  instance        { xsd:anyURI }? ),
       anyNsElement
     }

   anyNsElement =
     (  element    ns:*  { anyNsElement | text }
      | attribute  *     { text })*

请注意,该 schema 仅作为文档使用,而不是捕获 XML 格式 所有约束的规范性 schema。可以使用其他 XML schema 语言来定义一组 类似的约束(取决于所选 schema 语言的特性)。

该格式的媒体类型为 "application/problem+xml"。

扩展数组和对象序列化到 XML 格式时,会将包含一个或多个子元素的元素 视为表示一个对象,但只包含一个或多个名为 "i" 的子元素的元素除外, 后者被视为数组。例如,上面的示例在 XML 中如下所示:

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

<?xml version="1.0" encoding="UTF-8"?>
<problem xmlns="urn:ietf:rfc:7807">
  <type>https://example.com/probs/out-of-credit</type>
  <title>You do not have enough credit.</title>
  <detail>Your current balance is 30, but that costs 50.</detail>
  <instance>https://example.net/account/12345/msgs/abc</instance>
  <balance>30</balance>
  <accounts>
    <i>https://example.net/account/12345</i>
    <i>https://example.net/account/67890</i>
  </accounts>
</problem>

此格式使用 XML namespace,主要是为了允许将其嵌入到其他 基于 XML 的格式中;这并不意味着它可以或应当使用其他 namespace 中的元素或属性进行扩展。 RELAX NG schema 明确只允许来自 XML 格式中所用单一 namespace 的元素。 任何扩展数组和对象MUST 仅使用该 namespace 序列化为 XML 标记。

使用 XML 格式时,可以在 XML 中嵌入一条 XML 处理指令, 指示客户端使用所引用的 XSL Transformations (XSLT) 代码 [XSLT] 转换 XML。 如果该代码将 XML 转换为 (X)HTML,则可以提供 XML 格式,同时让能够执行该 转换的客户端显示在客户端渲染并展示的人类友好型 (X)HTML。请注意, 使用这种方法时,建议使用 XSLT 1.0,以最大化能够执行 XSLT 代码的客户端数量。

附录 C. 将问题详情用于 其他格式

在某些情况下,将问题详情嵌入到这里所描述格式以外的格式中可能是有利的。 例如,使用 HTML [HTML5] 的 API 也可能希望使用 HTML 来表达其问题 详情。

可以通过将现有序列化之一(JSON 或 XML)封装进其他格式, 或通过将问题详情的模型(如第 3 节中指定) 转换为该格式的约定,把问题详情嵌入其他格式。

例如,在 HTML 中,可以通过在 script 标签中封装 JSON 来嵌入一个问题:

<script type="application/problem+json">
  {
   "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"]
  }
</script>

或者,通过定义到 Resource Description Framework in Attributes (RDFa) [RDFA] 的映射来实现。

本规范不就如何在其他格式中嵌入问题详情提出具体建议; 适当的嵌入方式取决于正在使用的格式以及该格式的应用。

附录 D. 相对于 RFC 7807 的更改

本次修订作出了以下更改:

致谢

作者感谢 Jan AlgermissenSubbu AllamarajuMike AmundsenRoy FieldingEran HammerSam JohnstonMike McCallJulian ReschkeJames Snell 提供的评论和建议。

作者地址

Mark Nottingham
Prahran
Australia
Erik Wilde
Sanjay Dalal
United States of America