问题详情 (RFC 9457):做好 API 错误处理

  2024 年 5 月 2 日

HTTP API 在协调跨软件应用程序的无缝价值交换方面发挥着关键作用。这些无形的数据高速公路是我们日常使用的服务(从社交媒体平台到移动银行应用程序)的基础。然而,与任何形式的通信一样,清晰和结构至关重要,尤其是在传达“坏消息”时,例如错误。不幸的是,API 交互中有效的错误通信常常被忽视,导致混淆、沮丧以及诊断和解决问题的效率低下。

这是关于问题详情的两部分系列的第一部分。 有关第二部分,请点击此处。

有效地传递坏消息

有效地传递坏消息(如 API 错误)的关键不仅在于传递本身,还在于确保消息结构化、信息丰富,最重要的是可操作。历史上,API 传达错误的方式差异很大,导致了错误格式的混乱局面,每种格式都有其假设和特质。这种不一致不仅使开发人员的错误处理成为一场噩梦,而且还阻碍了不同系统之间的互操作性。随着我们在这个不断增长的 API 迷宫中导航,挑战也随之增加。错误响应中缺乏标准化不仅仅是一个小小的麻烦,它还是一个障碍。它延长了集成时间,增加了集成成本,并将持续维护变成了真正的总拥有成本 (TCO) 问题。随着新一波 API 消费者(如 AI 机器人和模型)的出现,这一挑战只会加剧。这些消费者需要精确和清晰度,而当前的错误消息混乱情况无法提供这些。

认识到这一痛点,互联网工程任务组 (IETF) 引入了 RFC 7807 [1],“HTTP API 的问题详情”,创建了一个以更结构化和更有帮助的方式表达错误的标准。

随着数字格局的不断发展,标准必须适应新挑战和新见解的步伐。因此,RFC 7807 已被 RFC 9457 [2] 取代,标志着我们如何传达 API 错误的重大演变。此更新不仅改进了原始标准,还引入了新功能以进一步增强错误报告。本质上,RFC 9457 旨在完善传递坏消息的艺术,确保 API 错误不仅被传达,而且以消除假设、有助于快速诊断并促进机器之间更顺畅的交互的方式进行。

当我们深入研究 RFC 9457 带来的进步时,了解为什么改进我们的 API 错误报告方法至关重要。这不仅是为了让开发人员的生活更轻松,还为了创建更具弹性、易于理解和用户友好的数字服务。

API 错误处理的反模式

尽管错误处理非常重要,但它常常被事后考虑,导致一系列反模式,从而使 API 消费和集成变得复杂。

以下是一些常见的反模式

  • 不提供有用的错误反馈:任何 API 的基本期望之一是它将通过提供有意义的反馈来指导消费者解决错误。当 API 无法提供有用的错误消息时,它会将开发人员置于黑暗之中,迫使他们依赖猜测、试错和调试来了解哪里出了问题。这不仅会减慢开发速度,还会增加集成时间和成本。
  • 发明自定义的错误传达方式:我们希望提供者在如何使用 API 解决问题方面具有创造力,但也许不希望在如何传达错误方面具有创造力。发明独特的错误报告方法,偏离既定标准会导致缺乏一致性,从而使 API 消费者需要为他们使用的每个 API 调整不同的错误处理机制。这种可变性使通用错误处理例程的开发变得复杂,使集成更加麻烦且容易出错。
  • 将错误隐藏在成功的响应中:有时,API 会将错误隐藏在看起来是成功的响应中,例如将错误详细信息嵌入 200 OK 状态中。这种做法会误导消费者认为请求成功,而实际上并非如此,从而使错误检测和处理变得复杂。它混淆了交互的真实性质,导致误解和错误的应用程序逻辑。
  • 泄漏堆栈跟踪信息:错误处理不仅会影响开发人员的体验。不良的选择也可能导致安全问题。一些 API 会在错误响应中无意中暴露过多信息,例如详细的堆栈跟踪。虽然这样做可能是为了帮助调试,但这会构成重大的安全风险,为潜在的攻击者提供了对 API 底层实现和结构的见解。这种信息泄漏可用于创建更有针对性的攻击,使整个应用程序面临风险。
  • 每个 API 对错误的响应不同:缺乏统一的错误报告方法意味着每个 API 都可能选择以不同的方式传达错误,无论是在结构还是内容方面。这种不一致是 API 消费者面临的最大挑战之一,尤其是在将多个 API 集成到单个应用程序中时。它需要为每个 API 定制错误处理,从而增加了应用程序的复杂性和维护开销。当您扩展以提供更多 API 时,如何处理错误应成为您 API 治理职责的一部分。

不良 API 错误处理的影响

上面列出的反模式会导致一系列超出仅仅是不便的问题,并且会影响 API 的成功。

  • 增加开发时间和成本:在确信工作完成后,开发人员会花费大量时间来解读错误并为每个 API 实现自定义处理程序。延长集成时间会增加与获取 API 以及持续维护相关的总体成本。
  • 糟糕的开发人员体验:缺乏清晰、一致的错误响应会让开发人员感到沮丧,可能会阻止他们使用 API。
  • 安全漏洞:通过错误泄漏实现细节可能会使 API 面临安全漏洞。这不是一个“如果”,而是一个“何时”会发生的问题!
  • 集成复杂性:不同的错误报告标准会增加集成的复杂性和脆弱性。这很可能会导致消费者流失,从而选择更稳定的 API。

什么是 HTTP API 的问题详情?

最初由 RFC 7807 引入,最近在 RFC 9457 中进一步改进,“HTTP API 的问题详情”是一个标准,提供了一个以结构化、一致和机器可读的格式表达错误详情的蓝图。它的设计目的是使错误响应更具信息性和可操作性,不仅适用于人类开发人员,还适用于在运行时使用 API 的系统。随着 RFC 9457 的发布,该标准已得到增强,以方便包含更多上下文和元数据,以帮助诊断和解决问题,以及用于托管常见问题类型 URI 的 IANA 注册表 [3]

问题详情对象结构以一种可以在不同系统和技术之间普遍理解的方式封装错误信息。

  • type:一个 URI 引用,用于标识问题类型。它的目的是为人类操作员提供一个查找有关错误的更多信息的位置。如果不存在或不适用,则假定为“about:blank”。
  • status:此问题发生时源服务器生成的 HTTP 状态代码。
  • title:问题类型的简短、人类可读的摘要。除非为了本地化,否则问题发生时它不应发生变化。
  • detail:特定于此问题发生的人类可读的解释。与标题不同,此字段的内容可能会因发生情况而异。
  • instance:一个 URI 引用,用于标识问题的具体发生实例。它在被取消引用时可能会或可能不会提供更多信息。
  • 扩展:可以添加任何字段,以便为消费客户端提供额外的的信息或上下文。建议使用扩展而不是让客户端解析 `detail` 属性。还建议在此处采用必须忽略模式来处理客户端应如何使用信息,因此应期望它们忽略任何未明确支持的额外字段。

这是一个包含两个扩展属性(代码和一个错误数组)的问题详情响应[4]示例。

{
    "type":"https://problems-registry.smartbear.com/missing-body-property",
    "status":400,
    "title":"Missing body property",
    "detail":"The request is missing an expected body property.",
    "code":"400-09",
    "instance":"/logs/regisrations/d24b2953-ce05-488e-bf31-67de50d3d085",
    "errors":[
       {
          "detail":"The body property {name} is required",
          "pointer":"/name"
       }
    ]
 }

请查看第二部分:问题详情 (RFC 9457):动手实践 API 错误处理

结论

问题详情是用于有效 API 错误通信的重要机制。通过解决长期困扰 HTTP API 的常见反模式,该标准为更可靠、更安全和更用户友好的 API 生态系统铺平了道路。随着我们的发展,采用这种标准化实践的重要性只会继续增长,尤其是在我们日益互联的世界中。

参考 描述 URL
[1] RFC 7807 - HTTP API 的问题详情 https://tools.ietf.org/html/rfc7807
[2] RFC 9457 - RFC 7807 的更新 https://www.rfc-editor.org/info/rfc9457
[3] 问题类型 IANA 注册表 https://www.iana.org/assignments/http-problem-types
[4] 问题详情响应示例 https://problems-registry.smartbear.com/missing-body-property