当前位置: 首页 > 工具软件 > Fluent-json > 使用案例 >

Json-schema 快速入门

羊舌航
2023-12-01

介绍

以下示例决不包含 JSON Schema 可以提供的所有值。为此,您需要深入了解规范本身——在https://json-schema.org/specification.html了解更多信息。

假设我们正在与基于 JSON 的产品目录进行交互。该目录的产品具有:

  • 标识符:productId
  • 商品名称:productName
  • 消费者的销售成本:price
  • 一组可选标签:tags.

例如:

{
  "productId": 1,
  "productName": "A green door",
  "price": 12.50,
  "tags": [ "home", "green" ]
}

虽然通常很简单,但该示例留下了一些悬而未决的问题。这里只是其中的几个:

  • 是什么productId
  • productName必需的吗?
  • 可以price为零(0)吗?
  • 是所有的tags字符串值吗?

当您谈论数据格式时,您希望获得有关键含义的元数据,包括这些键的有效输入。JSON Schema是一个提议的 IETF 标准,如何回答这些数据问题。

从Schema开始

要开始模式定义,让我们从基本的 JSON 模式开始。

我们从四个称为关键字的属性开始,它们表示为JSON键。

是的。该标准使用 JSON 数据文档来描述数据文档,通常也是 JSON 数据文档,但可以是任意数量的其他内容类型,例如text/xml.

  • $schema关键字表示此模式是根据标准的特定草案编写的,并且出于各种原因使用,主要是版本控制。
  • 关键字定义了模式的$idURI,以及模式中其他 URI 引用所针对的基本 URI。
  • titledescription注释关键字只是描述性的。它们不会对正在验证的数据添加约束。使用这两个关键字来说明模式的意图。
  • 验证关键字定义了我们的 JSON 数据的type第一个约束,在这种情况下它必须是一个 JSON 对象。
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product in the catalog",
  "type": "object"
}

我们在启动模式时引入以下术语:

定义属性

productId是唯一标识产品的数值。由于这是产品的规范标识符,因此没有一个产品是没有意义的,因此它是必需的。

在 JSON Schema 术语中,我们更新我们的模式以添加:

  • properties验证关键字。

  • productId关键 。

  • description注意到模式注释和type验证关键字——我们在上一节中介绍了这两个。

  • required验证关键字productId列表。

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    }
  },
  "required": [ "productId" ]
}
  • productName是描述产品的字符串值。由于没有名称的产品并不多,因此它也是必需的。
  • 由于required验证关键字是一个字符串数组,我们可以根据需要记录多个键;我们现在包括productName.
  • productId和 之间并没有真正的区别productName——为了完整起见,我们将两者都包括在内,因为计算机通常关注标识符,而人类通常关注名称。
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    }
  },
  "required": [ "productId", "productName" ]
}

深入了解属性

据店主说,没有免费的产品。

  • 使用前面介绍price的常用description模式注释和type验证关键字添加密钥。它也包含在由required验证关键字定义的键数组中。
  • 我们使用验证关键字 指定的值price必须不是零。exclusiveMinimum
  • 如果我们想包含零作为有效价格,我们将指定minimum验证关键字。
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    }
  },
  "required": [ "productId", "productName", "price" ]
}

接下来,我们来到tags关键。

店主是这么说的:

  • 如果有标签,则必须至少有一个标签,
  • 所有标签必须是唯一的;单个产品中没有重复。
  • 所有标签都必须是文本。
  • 标签很好,但它们不需要存在。

所以:

  • tags密钥添加了通常的注释和关键字。
  • 这次type验证关键字是array.
  • 我们引入了items验证关键字,以便我们可以定义数组中出现的内容。在这种情况下:string通过type验证关键字的值。
  • minItems验证关键字用于确保数组中至少有一项。
  • 验证关键字指出数组中的uniqueItems所有项目必须彼此唯一。
  • 我们没有将此键添加到required验证关键字数组中,因为它是可选的。
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    },
    "tags": {
      "description": "Tags for the product",
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "uniqueItems": true
    }
  },
  "required": [ "productId", "productName", "price" ]
}

嵌套数据结构

到目前为止,我们一直在处理一个非常扁平的模式——只有一个级别。本节演示嵌套数据结构。

  • dimensions使用我们之前发现的概念添加密钥。由于type验证关键字是object 我们可以使用 properties 验证关键字来定义嵌套数据结构。

  • 为简洁起见,我们在示例中省略了descriptionannotation 关键字。虽然在这种情况下通常最好彻底注释,但大多数开发人员都非常熟悉结构和键名。

  • 您会注意到required验证关键字的范围适用于维度键而不是超出范围。

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    },
    "tags": {
      "description": "Tags for the product",
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "dimensions": {
      "type": "object",
      "properties": {
        "length": {
          "type": "number"
        },
        "width": {
          "type": "number"
        },
        "height": {
          "type": "number"
        }
      },
      "required": [ "length", "width", "height" ]
    }
  },
  "required": [ "productId", "productName", "price" ]
}

架构外的引用

到目前为止,我们的 JSON 模式已经完全独立。为了重用、可读性和可维护性等原因,在许多数据结构中共享 JSON 模式是很常见的。

对于这个例子,我们引入了一个新的 JSON Schema 资源和其中的两个属性:

  • 我们使用minimum前面提到的验证关键字。
  • 我们添加maximum验证关键字。
  • 结合起来,这些为我们提供了用于验证的范围。
{
  "$id": "https://example.com/geographical-location.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Longitude and Latitude",
  "description": "A geographical coordinate on a planet (most commonly Earth).",
  "required": [ "latitude", "longitude" ],
  "type": "object",
  "properties": {
    "latitude": {
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "longitude": {
      "type": "number",
      "minimum": -180,
      "maximum": 180
    }
  }
}

接下来,我们添加对这个新模式的引用,以便可以合并它。

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    },
    "tags": {
      "description": "Tags for the product",
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "dimensions": {
      "type": "object",
      "properties": {
        "length": {
          "type": "number"
        },
        "width": {
          "type": "number"
        },
        "height": {
          "type": "number"
        }
      },
      "required": [ "length", "width", "height" ]
    },
    "warehouseLocation": {
      "description": "Coordinates of the warehouse where the product is located.",
      "$ref": "https://example.com/geographical-location.schema.json"
    }
  },
  "required": [ "productId", "productName", "price" ]
}

查看我们定义的 JSON Schema 的数据

自从我们最早的样本数据(向上滚动到顶部)以来,我们当然已经扩展了产品的概念。让我们看一下与我们定义的 JSON Schema 匹配的数据。

  {
    "productId": 1,
    "productName": "An ice sculpture",
    "price": 12.50,
    "tags": [ "cold", "ice" ],
    "dimensions": {
      "length": 7.0,
      "width": 12.0,
      "height": 9.5
    },
    "warehouseLocation": {
      "latitude": -78.75,
      "longitude": 20.4
    }
  }
 类似资料: