跳到主要内容

4. 定义新的问题类型 (Defining New Problem Types)

当 HTTP API 需要定义一个表示错误条件的响应时, 通过定义新的问题类型来实现可能是合适的.

在这样做之前, 重要的是理解问题类型适合用于什么, 以及哪些内容最好留给其他机制处理.

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

同样, 真正通用的问题, 即可能适用于 Web 上任何资源的条件, 通常最好用普通状态码表示. 例如, "write access disallowed" 问题可能没有必要, 因为对 PUT 请求返回 403 Forbidden 状态码已经不言自明.

最后, 应用程序可能已有更合适的方式, 用其已经定义的格式携带错误. 问题详情旨在避免必须建立新的 "fault" 或 "error" 文档格式, 而不是替代现有的领域特定格式.

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

新的问题类型定义必须 (MUST) 记录:

  1. type URI (通常使用 "http" 或 "https" scheme)

  2. 一个适当描述它的 title (应简短)

  3. 与其一起使用的 HTTP 状态码

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

问题类型 URI 应当 (SHOULD) 解析为 HTML [HTML5] 文档, 说明如何解决该问题.

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

如果定义了此类额外成员, 其名称应当 (SHOULD) 以字母开头 (ALPHA, 按 [ABNF] Appendix B.1), 并应当 (SHOULD) 由 ALPHA、DIGIT ([ABNF] Appendix B.1) 和 "_" 中的字符组成 (以便能序列化为 JSON 之外的格式), 且长度应当 (SHOULD) 为三个或更多字符.

4.1. 示例 (Example)

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

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

为此, 你可以在注册表 (Section 4.2) 中查找是否已有适合用途的已定义 type URI. 如果有, 可以重用该 URI.

如果没有可用 URI, 你可以创建并记录一个新的 type URI (它应由你控制并随时间保持稳定)、一个适当的 title 以及将与其一起使用的 HTTP 状态码, 同时说明它的含义以及应如何处理.

4.2. 已注册的问题类型 (Registered Problem Types)

本规范为常见且广泛使用的问题类型 URI 定义了 "HTTP Problem Types" 注册表, 以促进重用.

根据 [RFC8126] Section 4.6, 此注册表的策略为 Specification Required.

评估请求时, 指定专家应考虑社区反馈、问题类型定义的完善程度以及本规范的要求. 供应商特定、应用程序特定和部署特定的值不能注册. 规范文档应以稳定、可自由获取的方式发布 (理想情况下位于某个 URL), 但不需要是标准.

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

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

Type URI: [问题类型的 URI]
Title: [问题类型的简短描述]
Recommended HTTP status code: [最适合与该类型一起使用的状态码]
Reference: [定义该类型的规范]

关于注册请求发送位置的详细信息, 请参见 https://iana.org/assignments/http-problem-types 上的注册表.

4.2.1. about:blank

本规范注册一个 Problem Type, "about:blank", 如下.

Type URI: about:blank
Title: See HTTP Status Code
Recommended HTTP status code: N/A
Reference: RFC 9457

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

使用 "about:blank" 时, title 应当 (SHOULD) 与该状态码的推荐 HTTP 状态短语相同 (例如 404 对应 "Not Found" 等), 但可以 (MAY) 根据客户端偏好 (通过 Accept-Language 请求头表达) 进行本地化.

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