拥抱 JSON:架构验证如何增强您的 API
JSON(JavaScript 对象表示法)已成为 REST API 和 Web 服务中数据交换的事实上的标准。其简单的基于文本的格式使 JSON 易于阅读和解析,同时保持轻量级和高性能。与 XML 不同,JSON 直接映射到 JavaScript、Python、Ruby 和 Java 等现代编程语言中的本机数据结构,从而无需自定义解析器。
通过 API 进行交互的单页应用程序、移动应用程序和 IoT 设备的兴起巩固了 JSON 在序列化数据传输方面的受欢迎程度。它的普遍性使得 JSON 成为实现不同系统之间通信的自然选择。 JSON 的简单性、通用性和内置语言支持已证明它是一种有弹性、可扩展的数据交换格式。
定义严格的 JSON 模式允许开发人员在运行时验证数据格式和值。这提高了 API 的整体质量和可靠性。定义良好的 JSON 模式充当 API 客户端和服务器之间的契约,减少歧义和可能的故障点。本文探讨 JSON 架构定义、验证工具、设计技巧等。
定义 JSON 模式
JSON Schema 定义 JSON 文档的结构和数据类型。它用于验证以确保结构符合预期。
JSON 架构本身就是一个 JSON 文件,它声明其他 JSON 文档的形状。该架构指定了如下要求:
- JSON 对象可以包含哪些属性
- 必需属性与可选属性
- 字符串、数字、数组等值的数据类型
- 字符串的长度限制或允许的值集
JSON 架构的一些关键组件包括:
$schema- 声明 JSON 架构版本type- 数据类型(对象、数组、字符串等)properties- 将对象的属性指定为键值对required- 列出哪些对象属性是必需的additionalProperties- 是否允许额外的未指定属性minLength/maxLength- 字符串长度范围minimum/maximum- 数值范围enum- 允许的值选项
模式允许验证 JSON 文档是否与声明的结构匹配。它们充当 API 生产者和消费者之间的合同。明确定义的模式使集成更容易,界面更具弹性。
架构验证根据预定义架构验证 JSON 数据是定义 JSON 架构的最大好处之一。架构验证可确保发送到 API 和从 API 发出的 JSON 负载与预期的数据格式匹配。
当客户端向您的 API 发出请求时,可以在请求负载到达您的应用程序代码之前根据您的请求架构对其进行验证。这可以保护您的 API 免受不良数据的影响,并确保输入符合您的应用程序的预期。
同样,可以根据响应模式验证来自 API 的响应。这保证了 API 输出与合约匹配,并且客户端可以可靠地解析响应。
模式验证有几个优点:
- 通过拒绝无效的数据格式尽早发现错误
- 加强 API 合约和数据结构的纪律
- 减少对客户端和服务器代码中数据形状的假设
- 提供明确的使用和集成期望
- 作为文档并指导实施
- 轻松将现有管道中的验证与 JSON 模式库集成
- 可以生成多种语言的验证代码,例如 TypeScript
总的来说,JSON 模式验证是健壮且可维护的 API 的基本实践。定义模式只是成功的一半 - 针对这些模式进行验证使模式真正变得生动起来。
验证工具
JSON 架构验证可确保您的 JSON 数据符合预期格式。有几个用于模式验证的有用开源库:
-
Ajv - 用 JavaScript 编写的快速 JSON 模式验证器。支持 04/06/07 草案。
-
jsonschema - Python 的 JSON 模式实现。
-
JSV - 用 JavaScript 编写的独立 JSON 模式验证器。
-
json-schema-validator - JSON 模式草案 04-07 的 Node.js 验证器。
-
JaySchema - Java 的 JSON 模式验证器。
-
Jsonix Schema Compiler - 在 JavaScript 中生成模式验证器。
-
Go JSON 模式验证器 - 用 Go 编写的 JSON 模式验证器。这些库允许根据架构验证 JSON 数据,以便及早发现格式问题。它们很容易集成到构建管道和测试套件中,以强制架构合规性。大多数支持最新的 JSON 模式草案,并且可配置验证严格性。
模式设计技巧
设计 JSON 架构时,请遵循以下最佳实践:
-
保持模式简单和模块化。将模式定义分解为可根据需要组合的逻辑块。避免大型整体模式。
-
使用描述性且一致的属性名称,例如
firstName而不是缩写。 -
为您的架构和属性提供清晰的描述和标题。
-
制定适当的属性为必需属性或可选属性。仅当需要数据时才设置必需的属性。
-
在适当的情况下使用
minLength和maxLength约束字符串值。 -
使用枚举来表示小型固定的预定义值集。
-
定义属性的预期数据类型和格式。例如,对整数使用
integer,对时间戳使用string和format: date-time。 -
为
minimum: 0或maximum: 100等数字属性设置相关的最小值和最大值。 -
在有意义的情况下使用可选属性的默认值。
-
仅在适当的情况下使用
"type": ["string", "null"]而不仅仅是"type": "string"允许空值。 -
在需要时使用
"uniqueItems": true验证唯一性。 -
使用
"$ref"来引用和重用定义而不是重复。 -
编写客户可以理解的清晰的验证错误消息。
-
提供每个模式的有效和无效数据的示例。
-
使用
"$comment"字段来记录您的模式。 -
随着模式的发展对您的模式进行版本控制。
遵循架构设计最佳实践将提高 JSON API 的可维护性、可测试性和可用性。
常见陷阱
设计 JSON 模式时,重要的是要避免一些可能导致模式脆弱或难以维护的常见错误:
过于严格的验证
人们很容易使模式变得非常严格以尝试考虑每种可能性。然而,这使得模式难以更新并且经常阻塞有效数据。从基本验证开始,仅在真正需要时添加更多约束。
版本:“2.0.0”无处不在
最好避免在每个模式中使用 "version": "2.0.0" ,除非您计划在每次更改时增加它。这会增加开销,并且在大多数情况下无法提供有意义的版本控制。请改用标签或修订 ID。
不规划可扩展性模式应该考虑未来的新属性和数据。仅需要您当前需要的属性并允许其他属性。
忽略数据变体
数据格式通常具有多种允许的表示形式,例如日期或 ID。模式应该允许常见的变体以避免验证错误。
过于复杂的嵌套对象
对象和数组嵌套得太深会使模式难以理解和修改。尽量保持模式相对平坦。将重用的嵌套元素分解为定义。
不记录决策
使用描述记录在模式中做出验证决策的原因。这有助于未来的维护人员了解基本原理和预期用途。
从一开始就遵循架构最佳实践有助于避免这些常见的错误。让架构专注于核心验证并允许灵活扩展。
模式演变
JSON 模式需要随着需求的变化而不断发展。这涉及到进行可能会破坏现有客户端的更新。模式演化需要 API 提供者和消费者之间的仔细规划和沟通。
有几种处理架构更改的方法:
-
对您的架构进行版本控制并在新版本中进行不兼容的更改。允许客户指定他们支持的版本。
-
引入新的可选属性,不会破坏现有客户端。稍后在客户端有时间更新后才需要属性。
-
使用“anyOf”构造同时允许新旧模式变体。逐渐将客户端过渡到新架构。
-
对于重大变更,请提供提前通知和迁移说明。最初在功能切换后面或金丝雀集群上应用更改。
-
使用存储模式历史记录和元数据的模式注册表。这有助于跨服务集中管理架构生命周期。
-
提供工具来检测架构更改、迁移数据并生成更新的客户端模型。尽可能多地自动化转换。
发展模式时,仔细规划至关重要。尽早向消费者清楚地传达变化。在转换期间支持旧模式。尽可能自动化迁移机制。通过良好的模式治理,团队可以随着时间的推移调整模式,同时避免对客户造成重大破坏性更改。
生成代码定义 JSON 架构的主要好处之一是能够自动生成代码以供客户端使用架构。这消除了手动编写模型和序列化器,从而节省了大量的开发时间和精力。有多种工具可以从 JSON 模式生成代码:
-
Quicktype - 一种开源工具,可为超过 35 种语言生成类型和解析器,包括 TypeScript、C#、Java、Go 和 Swift。它支持具有枚举、可为空类型、联合和泛型等功能的复杂模式。
-
JSON Schema Codegen - 一个 Java 命令行工具,可以从 JSON Schema 生成 Java、C#、Go、Typescript、JavaScript、Swift、Kotlin 和 Rust 代码。它有一个插件生态系统,允许自定义代码生成。
-
JWT 架构 - 专注于基于 JSON 架构为 JWT 令牌生成代码。支持 Java、Typescript、C#、Go、Ruby 和 PHP。
-
GraphQL 代码生成器 - 主要用于生成 GraphQL 模式和解析器代码,但也支持从 JSON 模式生成 TypeScript 类型。
-
API 脚本 - 适用于 Windows 和 Mac 的基于 GUI 的工具,可生成 TypeScript、C#、Java、Go、Ruby 等代码。包括一个模拟服务器来测试生成的代码。
-
JSONSchema2Pojo - 用于从 JSON 模式生成 Java POJO 的 Maven 和 Gradle 插件。可通过注释和可配置规则进行定制。
自动生成的代码节省了大量重复工作并强制执行模式中定义的结构。生成的模型可以直接导入到应用程序代码库中,并根据需要在顶部添加其他自定义。整体模式驱动的代码生成简化了开发,并有助于确保 API 接口和实现之间的一致性。
架构注册表
模式注册表提供了用于模式存储和检索的集中存储库。它支持跨具有多个应用程序和服务的大型组织进行大规模模式管理。模式注册表的主要优点包括:
-
集中模式存储 - 所有模式定义都存储在一个位置,提供单一事实来源。这可以避免重复和不一致。
-
架构版本控制 - 注册表维护每个架构的版本。这支持模式随着时间的推移以受控的方式演变。新模式不会破坏现有消费者。
-
架构查找 - 服务可以轻松地按 ID 或主题查找架构定义。减少生产者和消费者之间的耦合。- 架构兼容性检查 - 注册表可以检查新架构版本和现有版本之间的兼容性。防止引入重大更改。
-
模式演变治理 - 注册表策略控制模式如何随时间演变。例如,强制某些主题的向后兼容性。
-
性能和可扩展性 - 模式的集中缓存可提高性能。水平扩展注册表可以处理负载。
模式注册表对于使用 Apache Kafka 的事件驱动架构的大规模生产部署至关重要。流行的开源选项包括 Confluence SchemaRegistry 和 ApicurioRegistry。注册表是通过模式和模式验证实现健壮且可靠的数据交换的关键组件。
结论
正如我们所探索的,JSON 模式在现代 API 架构中定义期望和验证数据方面发挥着至关重要的作用。通过创建精确的 JSON 模式,开发人员可以为请求和响应负载建立清晰的契约。这提高了 API 客户端和服务器之间的可靠性、稳健性和理解。
JSON Schema 等架构验证工具提供了根据架构验证 JSON 数据的内置功能。这有助于及早发现错误并确保使用正确的格式。验证可以防止不良数据导致后续故障。
设计 JSON 模式时,关注清晰度、灵活性和兼容性非常重要。模式应该捕捉数据格式的本质,但又不会受到过度限制。允许架构以向后兼容的方式发展,使 API 能够在不破坏现有客户端的情况下进行改进。
总体而言,JSON 模式和验证为 API 开发提供了重大好处。通过模式定义严格的契约可以实现独立和模块化的软件系统。验证使开发人员确信数据符合定义的规范。强大的架构和验证是可扩展且可靠的 API 架构的关键推动因素。
随着 JSON 和 REST API 的使用不断增长,开发强大的 JSON 模式仍然是 API 开发人员的一项基本技能。掌握架构设计和验证最佳实践对于构建高质量的 Web API 至关重要。请继续关注 APIRobots,了解有关这个令人兴奋的领域的更多见解和最新动态。不要错过 API 为您的业务带来的机会。立即通过 API Robots 和 API 开发机构 与我们联系,让我们一起释放 API 的全部潜力。