参考
JSON Schema 实现之间的通用接口
JSON Schema 非常广泛地使用,并且几乎同样广泛地实现。有针对超过 20 种语言或环境的 JSON Schema 验证实现。这种普及对用户选择来说非常棒 - 作为希望使用 JSON Schema 的人,你几乎可以肯定你会找到适合你的目标环境的实现。
但当涉及到社区支持时,可能很难知道如何在特定的库或实现中执行各种 JSON Schema 操作,因为每个操作可能具有略微不同(或者更甚于略微不同)的 API。当考虑到规范本身不一定规定或要求的行为时,这可能会变得特别具有挑战性,但无论如何,这种行为在实践中是常见的、有用的,甚至是被要求的行为,以便使用 JSON Schema。此页面旨在记录许多这些 *常见的操作*,记录许多实现跨现有的 JSON Schema 生态系统提供的接口。
对于每一个,我们首先使用来自规范的术语来命名和描述操作,或者使用旨在简洁而精确的术语。此页面的意图部分是作为 JSON Schema 操作的重要参考,以及一种为特定语言和实现量身定制帮助的方式。因此,我们在已知的情况下,包括跨实现的每个接口或功能部分的示例。此页面上各节的排序并不一定表示它们相对于彼此的重要性。功能的省略(即,如果你在下面找不到使用给定实现的方式) *不一定是* 实现不支持该功能的标志,尽管它可能意味着页面作者无法轻松找到它。来自实现者的贡献和更正特别受欢迎,文档链接也是如此!
为了使此页面的某些部分更精确,我们假设存在一组 *抽象类型*,所有这些类型都可以在下面引用,并且在给定的编程语言或实现中将具有特定的具体类型。除了 String
、Number
、Boolean
、Mapping
、Callable
等占位符类型,JSON Schema 相关的类型包括
模式
JSON 模式类型,它在 JSON Schema 的不同方言之间也可能有所不同。对于 JSON Schema 的常见或现代版本,这种类型本质上必须能够表示任意 JSON 对象以及布尔值。
实例
JSON 实例类型。此类型应该本质上是 Any
或能够表示所有 JSON 值的类型,鉴于 JSON Schema 适用于任何可表示的 JSON。
方言
JSON 方言或方言标识符类型。如果方言在实现中由其 URI 或某些简短名称表示,则此类型可能仅仅是 String
。
评估选项
*完全准备好的* 模式和实例类型, *以及* 任何其他特定于实现的自定义行为。至少,此类型要么是 Schema → Instance
,要么是 Schema × Instance
(取决于实现是将模式和实例一起使用还是编译模式,然后生成一个单独的函数来获取要验证的实例)。它很可能以至少以下几种方式变得更加丰富
- 鉴于可能需要某种形式的模式注册表来支持引用外部模式,这种类型可能会包含某种注册表,例如
Mapping<URI, Schema> → Schema → ...
。 - 如果某个实现支持自定义将哪些 JSON 类型匹配到哪些语言类型(如 下面讨论),那么这种类型可能包含此映射的某种表示,例如
Mapping<String, Callable[...]> → Schema → ...
封装了在评估期间将每种类型映射到的内容。 - 类似地,如果有用于 格式断言启用 的特定 API,那么
format
关键字的行为的某种表示存在于上下文中。 - 如果实现支持 创建或自定义方言,尤其是在模式可以在不同方言之间包含子模式的情况下,上下文将包含方言的某种表示,例如
Dialect → Schema → ...
。
结果
JSON Schema 验证结果的类型,即一个封装了给定 Instance
在 Schema
下的有效性的对象。在某些实现或语言中,这种类型可能仅仅是 Boolean
。
ResultWithAnnotations
包含在验证期间收集的 JSON Schema 注释的 JSON Schema 验证结果的类型。
URI
符合 RFC 3986 的 URI 的类型。这种类型通常不应与 String
相同,因为 URI 有多种可能的字符串表示,并且需要规范化才能具有正确的语义。
由于此页面处理跨越语言障碍的问题,并且不同的编程语言具有不同的功能,特别是在它们如何表示带外错误(通过异常、选项类型、包装器返回类型、哨兵值或其他机制)方面,因此此页面也引入了 1 用于表示包含对带外错误的显式表示的函数类型的特定符号。对这些类型的解释将取决于编程语言。用一个例子来解释上述内容会更容易。
考虑对浮点数的除法函数,表示为 x / y
。
我们将把此函数的类型写成 Float → Float → Float <!> DivideByZeroError
,其中此签名的解释是该函数接受 2 个浮点数并返回一个浮点数,但 <!>
信号它也可能传播 DivideByZeroError
(在这种情况下,当函数被要求除以零时)。
DivideByZeroError
的具体表现形式将取决于编程语言。在具有异常的语言中,此函数可能会将 DivideByZeroError
等效项作为异常抛出,该异常必须或可能由调用者处理。在具有选项类型的语言中,"正确" 的类型签名实际上可能包装在 Option
类型中,该类型表示除以零的情况(因此在这种语言中的"真实" 签名将是 Option[Float → Float → Float]
)。在具有包装器返回类型的语言中,真正的类型签名可能是 Result<Float, DivideByZeroError>
,其中返回的值必须被检查以确保它包含一个成功的结果,并且除以零错误是一个可能的错误值。在具有返回"垃圾"值的约定的语言中,真正的类型可能恰好是 Float → Float → Float
,其中当除以零时返回一些任意的浮点数,没有其他指示。
在所有上述情况下,当抛出异常(对应于错误或垃圾值)(对应于返回)时,我们按照惯例假设任何正常的返回值要么完全不存在于编程语言的机制中,要么被认为是毫无意义的。
此外,此页面通常不会考虑或提及可能由于除特定部分中讨论的以外的原因而引发错误的可能性。例如,上面提到的除法示例如果提供字符串,可能会在支持这种运行时可能性的动态类型语言中引发其他类型的错误,因此"真实" 的除法函数可能看起来更像 Float → Float → Float <!> DivideByZeroError | TypeError
甚至更进一步的错误可能性。在 JSON Schema 的情况下,这意味着下面提到的每个接口都包含一个类型,其中包含 <!> InvalidSchema | NotValidJSON | ...
代表它们被提供不符合规范的模式或不适合 JSON 数据模型等情况,但我们认为这些是隐式的,除非与正在讨论的接口直接相关,否则不会明确提及它们。
实例验证
实例验证是 JSON Schema 的关键功能之一。它是在特定模式下判断给定数据有效还是无效的过程。实现可能会提供以下一个或多个特定接口来执行此验证。
基于异常的验证
类型: EvaluationOptions → None <!> ValidationError
或 EvaluationOptions → Result <!> ValidationError
一个验证 API,当验证本身失败时会导致语言特定的失败或异常。如果成功,此 API 可能会返回包含更多详细信息的结果,或者可能只是静默地继续执行。
布尔验证
类型: EvaluationOptions
→ Boolean
一个 API,它生成一个简单的布尔结果,指示实例在模式下的有效性。
双参数验证
类型: Schema
× Instance
→ Result
一个 API,它同时接受模式和实例,并生成一个结果,指示实例在给定模式下是否有效。
从某种意义上说,双参数验证是 JSON Schema 验证中最简单的 API;它仅仅询问给定实例在给定模式下是否有效,没有关于重复使用(模式)或额外计算的假设。
重复验证 / 模式编译
类型: Schema
→ Instance
→ Result
一个 API,它尝试准备一个模式以供重复使用。它可能会(并且很可能会)执行某种形式的预优化,提前完成一些工作,这样在验证多个实例时就不需要重复。
子模式验证
类型: Schema
× String
× Instance
→ Result
一个 API,它支持使用包含在给定模式中的子模式来验证实例。
子模式通常通过 JSON 指针或等效语法来标识,与使用 $ref
关键字引用子模式的新模式进行验证相反。
注释收集
类型: EvaluationOptions
→ ResultWithAnnotations
一个 API,它收集在处理给定模式和实例时生成的注释。
模式验证
类型: Schema
→ Result
一个 API,它在模式编写的方言下验证模式本身。此 API 很可能使用相应的元模式(或元模式)来实现方言,但通常必须做额外的工作以确保即使在元模式中未检查的条件下模式也不无效。
显式版本选择
类型: Dialect
→ EvaluationOptions
→ Result
一个 API,它控制当给定一个没有其他指示其方言的模式时(即没有声明 $schema
属性),实现将假设哪个方言。
版本检测
类型: Schema
→ Dialect
一个 API,它标识给定模式编写的方言,返回方言本身或其他方言特定的验证函数。
类型自定义
一个 API,它允许(重新)配置哪些语言级类型对应于哪些 JSON Schema 类型,并可能允许定义新类型。
字符串验证
类型: String
→ String
→ Result
一个 API,它直接使用模式来验证实例,其中两者都表示为字符串 - 序列化 JSON - 而不是反序列化 JSON。
语言对象验证
类型: EvaluationOptions
→ Result
一个 API,它使用模式来验证实例,其中两者都已反序列化为语言级对象,或者可能直接以编程方式构建为语言级对象。
format
验证
格式断言启用
一个 API,用于配置format
关键字的行为,在一些方言中,这种行为并非完全由 JSON Schema 词汇表启用控制。
格式注册
类型: String
× (Instance
→ Boolean)→
EvaluationOptions`
一个 API,允许注册一个新的格式及其实现,以便与format
关键字一起使用,通常在用于断言时。
一些实现可能进一步允许为不同的方言注册不同的可用格式集。
格式查询
一个 API,用于查询或列出已注册的可用格式集。
直接格式验证
类型: String
× Instance
→ Boolean
一个 API,允许在没有模式存在的情况下直接检查类似 JSON 的值是否满足特定格式。
模式注册表填充
一个 API,用于配置在验证过程中可用于引用的模式捆绑包。
外部识别模式
一个 API,允许将一个或多个 URI 与模式关联,其中这些 URI 未由内部用$id
关键字(或特定于方言的等效项)指示。
内部识别模式
一个 API,允许将 URI 与模式关联,其中 URI 由模式中$id
关键字(或特定于方言的等效项)的存在内部指示。
模式发现
一个 API,用于(递归地)爬取根模式或模式,发现存在的任何子资源(子模式),并使这些子资源的 URI 可用于进一步引用。
动态 URI 解析
一个 API,允许对注册表中未预先填充的任何引用执行任意动态查找行为。
输出格式选择/生成
一个 API,用于配置在生成结果时使用 JSON Schema 的哪种输出格式,或允许在给定Result
的情况下生成特定输出格式。
词汇表注册
一个 API,用于促进创建新的 JSON Schema 词汇表,通常用于在稍后构建新的方言时使用。
方言创建
一个 API,用于促进创建新的 JSON Schema 方言,通常以某种方式注册它们,以便它们可以在实现中进一步使用。
失败详情
一个 API,允许以编程方式检查特定验证失败的原因,至少包含导致失败的失败关键字、值和单独消息。