# 选择结构语言

¥Choosing schema language

# JSON 类型定义

¥JSON Type Definition

Ajv 支持专注于定义 JSON 消息/有效负载的跨平台类型的新规范 - JSON Type Definition (JTD).参见非正式参考 JTD 结构形式 和正式规范 RFC8927 (opens new window)

¥Ajv supports the new specification focussed on defining cross-platform types of JSON messages/payloads - JSON Type Definition (JTD). See the informal reference of JTD schema forms and formal specification RFC8927 (opens new window).

# JSON 结构

¥JSON Schema

Ajv 支持最广泛使用的 JSON Schema 规范草案。请参阅可用的 JSON 结构校验关键字规范草案 (opens new window) 的非正式参考。

¥Ajv supports most widely used drafts of JSON Schema specification. Please see the informal reference of available JSON Schema validation keywords and specification drafts (opens new window).

# 草案 04

¥draft-04

Draft-04 不包含在 Ajv v7 中,因为它与以下草案有一些差异:

¥Draft-04 is not included in Ajv v7, because of some differences it has with the following drafts:

  • 结构标识符的不同结构成员(draft-04 中的 id 而不是 $id

    ¥different schema member for schema identifier (id in draft-04 instead of $id)

  • ExclusiveMaximum/Minimum 的不同语法

    ¥different syntax of exclusiveMaximum/Minimum

你仍然可以将草案 04 架构与 Ajv v6 一起使用 - 虽然该功能已不再积极开发,但至少在 2021 年 6 月 30 日之前仍将支持任何与安全相关的问题。

¥You can still use draft-04 schemas with Ajv v6 - while this is no longer actively developed, any security related issues would still be supported at least until 30/06/2021.

安装 v6:

¥To install v6:

npm install ajv@6

你可以使用 ajv-cli (opens new window) 将结构从草案 04 迁移到草案 07。

¥You can migrate schemas from draft-04 to draft-07 using ajv-cli (opens new window).

# 草案 07(和草案 06)

¥draft-07 (and draft-06)

这些是 JSON Schema 规范最广泛使用的版本,并且主要的 ajv 导出支持它们。

¥These are the most widely used versions of JSON Schema specification, and they are supported with the main ajv export.

import Ajv from "ajv"
const ajv = new Ajv()

如果你需要支持草案 06 模式,则需要添加额外的元模式,但你可以只更改(或删除)模式中的 $schema 属性 - 不需要进行其他更改:

¥If you need to support draft-06 schemas you need to add additional meta-schema, but you may just change (or remove) $schema attribute in your schemas - no other changes are needed:

const draft6MetaSchema = require("ajv/dist/refs/json-schema-draft-06.json")
ajv.addMetaSchema(draft6MetaSchema)

# 2019-09 草案(和 2020-12 草案)

¥draft 2019-09 (and draft-2020-12)

与草案 07 相比,此 JSON 结构版本的主要优点是能够传播不允许跨多个结构使用其他属性的记录定义。如果你不需要它,那么使用 Draft-07 可能会更好。

¥The main advantage of this JSON Schema version over draft-07 is the ability to spread the definition of records that do not allow additional properties across multiple schemas. If you do not need it, you might be better off with draft-07.

要在所有 JSON 结构草案 2019-09/2020-12 功能的支持下使用 Ajv,你需要使用不同的导出:

¥To use Ajv with the support of all JSON Schema draft-2019-09/2020-12 features you need to use a different export:

import Ajv2019 from "ajv/dist/2019"
const ajv = new Ajv2019()

(可选)你可以添加 Draft-07 元结构,以在一个 Ajv 实例中同时使用 Draft-07 和 Draft-2019-09 结构:

¥Optionally, you can add draft-07 meta-schema, to use both draft-07 and draft-2019-09 schemas in one Ajv instance:

const draft7MetaSchema = require("ajv/dist/refs/json-schema-draft-07.json")
ajv.addMetaSchema(draft7MetaSchema)

Draft-2019-09 支持通过单独的导出提供,以避免增加 Draft-07 用户的打包包和生成的代码大小。

¥Draft-2019-09 support is provided via a separate export in order to avoid increasing the bundle and generated code size for draft-07 users.

通过此导入,Ajv 支持以下功能:

¥With this import Ajv supports the following features:

Draft-2019-09 具有性能成本(即使未使用时)

支持动态递归引用和 unevaluatedProperties/unevaluatedItems 关键字甚至会在不使用这些功能的校验函数中添加额外的生成代码(如果可能,Ajv 在编译时确定哪些属性/项是 "unevaluated",但对动态引用的支持始终会添加额外的生成代码 )。如果你没有在结构中使用这些功能,建议使用默认的 Ajv 导出和 JSON-Schema Draft-07 支持。

¥Supporting dynamic recursive references and unevaluatedProperties/unevaluatedItems keywords adds additional generated code even to the validation functions where these features are not used (when possible, Ajv determines which properties/items are "unevaluated" at compilation time, but support for dynamic references always adds additional generated code). If you are not using these features in your schemas it is recommended to use default Ajv export with JSON-Schema draft-07 support.

# 对比

¥Comparison

JSON 结构JSON 类型定义 都是跨平台规范,采用多种编程语言实现,定义 JSON 数据的形状。

¥Both JSON Schema and JSON Type Definition are cross-platform specifications with implementations in multiple programming languages that define the shape of your JSON data.

你可以在 入门 部分示例中看到两种规范之间的差异。

¥You can see the difference between the two specifications in Getting started section examples.

本节比较它们的优缺点,以帮助确定哪种规范更适合你的应用。

¥This section compares their pros/cons to help decide which specification fits your application better.

# JSON 结构

¥JSON Schema

Pros:

  • 规范广泛采用。

    ¥Wide specification adoption.

  • 用作 OpenAPI 规范的一部分。

    ¥Used as part of OpenAPI specification.

  • 支持复杂的校验场景:

    ¥Support of complex validation scenarios:

    • 未标记的联合和布尔逻辑

      ¥untagged unions and boolean logic

    • 条件结构和依赖

      ¥conditional schemas and dependencies

    • 对字符串、数组和对象的数字范围和大小的限制

      ¥restrictions on the number ranges and the size of strings, arrays and objects

    • 使用格式、结构和内容关键字进行语义校验

      ¥semantic validation with formats, patterns and content keywords

    • 跨多个结构分布严格的记录定义(带有 unevaluatedProperties)

      ¥distribute strict record definitions across multiple schemas (with unevaluatedProperties)

  • 可有效用于校验任何 JavaScript 对象和配置文件。

    ¥Can be effectively used for validation of any JavaScript objects and configuration files.

Cons:

  • 定义了数据的集合限制,而不是数据的形状。

    ¥Defines the collection of restrictions on the data, rather than the shape of the data.

  • 没有对标记联合的标准支持。

    ¥No standard support for tagged unions.

  • 对于新用户来说复杂且容易出错(Ajv 默认启用 严格模式 来弥补这一点,但它不是跨平台的)。

    ¥Complex and error prone for the new users (Ajv has strict mode enabled by default to compensate for it, but it is not cross-platform).

  • 规范的某些部分难以实现,从而产生实现分歧的风险:

    ¥Some parts of specification are difficult to implement, creating the risk of implementations divergence:

    • 参考解析模型

      ¥reference resolution model

    • unevaluatedProperties/unevaluatedItems

    • 动态递归引用

      ¥dynamic recursive references

  • 互联网草案状态(而不是 RFC)

    ¥Internet draft status (rather than RFC)

有关详细信息和已定义关键字的列表,请参阅 JSON 结构

¥See JSON Schema for more information and the list of defined keywords.

# JSON 类型定义

¥JSON Type Definition

Pros:

  • 与多种语言的类型系统保持一致 - 可用于生成类型定义以及与这些类型之间的高效解析器和序列化器。

    ¥Aligned with type systems of many languages - can be used to generate type definitions and efficient parsers and serializers to/from these types.

  • 非常简单,实现跨平台 JSON API 建模的最佳实践。

    ¥Very simple, enforcing the best practices for cross-platform JSON API modelling.

  • 易于实现,确保实现之间的一致性。

    ¥Simple to implement, ensuring consistency across implementations.

  • 通过严格定义的结构形式(而不是限制的集合)定义 JSON 数据的形状。

    ¥Defines the shape of JSON data via strictly defined schema forms (rather than the collection of restrictions).

  • 对标记联合的有效支持。

    ¥Effective support for tagged unions.

  • 旨在防止用户错误。

    ¥Designed to protect against user mistakes.

  • 支持将结构编译为高效的 序列化器和解析器(无需作为单独的步骤进行校验)。

    ¥Supports compilation of schemas to efficient serializers and parsers (no need to validate as a separate step).

  • 批准为 RFC8927 (opens new window)

    ¥Approved as RFC8927 (opens new window).

  • 自 2020 年标准化以来,Ajv v8.12.0 得到了广泛的行业采用,它修复了所有报告的 JTD 错误。

    ¥Substantial industry adoption since it was standardized in 2020, Ajv v8.12.0 fixed all reported JTD bugs.

Cons:

  • 与 JSON Schema 相比有限制 - 不支持未标记的联合1、条件、不同架构文件之间的引用2等。

    ¥Limited, compared with JSON Schema - no support for untagged unions1, conditionals, references between different schema files2, etc.

  • 规范中没有元模式3

    ¥No meta-schema in the specification3.

1 Ajv 定义了可以在 "metadata" 对象内部使用的非标准关键字 "union"。

¥1 Ajv defines non-standard keyword "union" that can be used inside "metadata" object.

2 你仍然可以在应用代码中组合多个文件的架构。

¥2 You can still combine schemas from multiple files in the application code.

3 Ajv 定义 JTD 模式的元模式。

¥3 Ajv defines meta-schema for JTD schemas.

有关详细信息和已定义结构形式的列表,请参阅 JSON 类型定义

¥See JSON Type Definition for more information and the list of defined schema forms.