离别繁琐的数据校验:用JSON Schema简化你的代码

1. JSON Schema

JSON Schema 是一种依据 JSON 的格局,用于描绘 JSON 数据的结构和验证 JSON 数据。它为 JSON 数据提供了一个明晰的描绘,能够用来验证、文档化,以及界定数据的接口。下面是 JSON Schema 的一些核心特色和运用方法的具体介绍:

  1. 描绘数据格局:运用 JSON Schema,你能够具体描绘 JSON 数据的预期结构,包含哪些字段是必需的,字段的数据类型是什么(如字符串、数字、布尔值等),以及字段的其他属性(如字符串的最小长度、最大长度、正则表达式模式等)。

  2. 数据验证:JSON Schema 最常见的用处之一是验证 JSON 数据。这意味着你能够依据界说的 schema 来查看 JSON 数据是否契合预期的格局,这在处理外部数据或 API 呼应时特别有用。如果数据不契合预期,你能够捕获这些过错并相应地处理它们。

  3. 主动生成文档:因为 JSON Schema 以标准化的格局描绘了数据的结构,它能够被用来主动生成文档。这关于 API 的文档化特别有用,因为开发者能够明晰地了解 API 接口期望接纳什么样的数据,以及 API 呼应将返回什么样的数据。

  4. 简化开发流程:通过运用 JSON Schema 来验证数据,开发者能够削减手动编写用于数据验证的代码量。这不只能够进步开发功率,还能够削减因为数据过错导致的 bug。

  5. 跨言语支撑:JSON Schema 有广泛的编程言语支撑,包含但不限于 JavaScript、Python、Java 和 C#。这意味着无论你运用什么编程言语,你都能够找到库来帮助你处理 JSON Schema。

  6. 版别控制:JSON Schema 自身也在不断开展,现在有多个版别。每个版别添加了新的功用并对现有功用进行了改善。这使得 JSON Schema 能够适应不断变化的需求,一起坚持向后兼容性。

通过运用 JSON Schema,开发者能够创立愈加健壮和可靠的运用程序,保证数据的一致性和准确性,一起进步开发功率和降低保护本钱。

2. 诞生布景

JSON Schema 的诞生布景源于对 JSON 数据格局的广泛采用及随之而来的需求验证 JSON 数据结构和内容的需求。JSON(JavaScript Object Notation)是一种轻量级的数据交换格局,易于人阅览和编写,一起也易于机器解析和生成。跟着 Web 服务和运用程序接口(API)的快速开展,JSON 成为了在网络上进行数据交换的一种流行方法。

在这种布景下,开发者和体系架构师面临着怎么有用验证 JSON 数据的挑战,特别是在杂乱体系和跨团队协作中,保证数据的一致性和正确性变得尤为重要。以下是 JSON Schema 出现的几个关键布景要素:

  1. 数据验证需求:跟着体系变得越来越依赖于动态和灵敏的数据交换,需求一种可靠的方法来验证数据结构和内容,以防止过错数据导致的问题。

  2. 主动化和标准化:在主动化处理过程中,如 API 的调用和呼应,需求有一个标准方法来描绘和验证数据,从而削减人为干涉和潜在的过错。

  3. 跨言语和跨渠道交互:作为一种与言语无关的数据格局,JSON 被广泛运用于不同编程言语和渠道之间的交互。JSON Schema 提供了一种统一的方法来界说和验证数据结构,促进了不同体系之间的互操作性。

  4. 文档和协作:JSON Schema 还能够用作文档,帮助开发者理解数据模型的结构,促进团队成员之间的沟通和协作。

因此,JSON Schema 应运而生,它不只处理了数据验证的问题,还支撑文档生成、主动化测验和开发工具集成等多种用处,成为了现代 Web 开发中不可或缺的一个组成部分。

3. TS vs JSON Schema

JSON Schema 和 TypeScript(TS)都用于保证数据结构的正确性,但它们在运用和意图上存在一些关键差异:

  1. 运用范围

    • JSON Schema:首要用于描绘和验证 JSON 数据结构,保证 JSON 数据契合预界说的格局。它是独立于编程言语的,能够用于网络传输中的数据验证、装备文件的验证等场景。
    • TypeScript:是 JavaScript 的一个超集,它添加了静态类型界说的功用。TypeScript 首要用于在编译时查看代码中的类型过错,进步开发功率和代码质量。
  2. 执行机遇

    • JSON Schema:通常在运行时用于验证数据,例如验证 API 恳求/呼应的数据结构。
    • TypeScript:在编译时进行类型查看,编译后的代码转换为一般的 JavaScript,运行时不会进行类型查看。
  3. 意图和运用场景

    • JSON Schema:用于保证数据恪守特定的格局和结构,常用于 API 数据交换和装备数据验证。
    • TypeScript:旨在通过引进静态类型体系来进步代码的可保护性和可读性,首要用于开发阶段,帮助开发者捕捉类型相关的过错。
  4. 言语和渠道

    • JSON Schema:是一个独立的标准,能够与任何支撑 JSON 的编程言语一起运用。
    • TypeScript:是一种编程言语,需求特定的编译器(TypeScript 编译器)将 TypeScript 代码转换为 JavaScript 代码。

JSON Schema 首要重视于运行时的数据验证,保证数据结构的正确性;而 TypeScript 重视于编译时的类型查看,提高开发过程中的代码质量和安全性。两者虽然在某些方面具有互补性,但服务于编程和数据处理的不同阶段和方面。

4. 示例

4.1 最小示例

{
  "$id": "https://example.com/person.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Person",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string",
      "description": "The person's first name."
    },
    "lastName": {
      "type": "string",
      "description": "The person's last name."
    },
    "age": {
      "description": "Age in years which must be equal to or greater than zero.",
      "type": "integer",
      "minimum": 0
    }
  }
}

数据:

{
  "firstName": "John",
  "lastName": "Doe",
  "age": 21
}

4.2 数组

{
  "$id": "https://example.com/arrays.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "A representation of a person, company, organization, or place",
  "type": "object",
  "properties": {
    "fruits": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "vegetables": {
      "type": "array",
      "items": { "$ref": "#/$defs/veggie" }
    }
  },
  "$defs": {
    "veggie": {
      "type": "object",
      "required": [ "veggieName", "veggieLike" ],
      "properties": {
        "veggieName": {
          "type": "string",
          "description": "The name of the vegetable."
        },
        "veggieLike": {
          "type": "boolean",
          "description": "Do I like this vegetable?"
        }
      }
    }
  }
}

数据:

{
  "fruits": [ "apple", "orange", "pear" ],
  "vegetables": [
    {
      "veggieName": "potato",
      "veggieLike": true
    },
    {
      "veggieName": "broccoli",
      "veggieLike": false
    }
  ]
}

4.3 枚举

{
  "$id": "https://example.com/enumerated-values.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Enumerated Values",
  "type": "object",
  "properties": {
    "data": {
      "enum": [42, true, "hello", null, [1, 2, 3]]
    }
  }
}

数据:

{
  "data": [1, 2, 3]
}

4.4 正则

{
  "$id": "https://example.com/regex-pattern.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Regular Expression Pattern",
  "type": "object",
  "properties": {
    "code": {
      "type": "string",
      "pattern": "^[A-Z]{3}-\d{3}$"
    }
  }
}

数据:

{
  "code": "ABC-123"
}

4.5 嵌套

{
  "$id": "https://example.com/complex-object.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Complex Object",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "integer",
      "minimum": 0
    },
    "address": {
      "type": "object",
      "properties": {
        "street": {
          "type": "string"
        },
        "city": {
          "type": "string"
        },
        "state": {
          "type": "string"
        },
        "postalCode": {
          "type": "string",
          "pattern": "\d{5}"
        }
      },
      "required": ["street", "city", "state", "postalCode"]
    },
    "hobbies": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": ["name", "age"]
}

数据:

{
  "name": "John Doe",
  "age": 25,
  "address": {
    "street": "123 Main St",
    "city": "New York",
    "state": "NY",
    "postalCode": "10001"
  },
  "hobbies": ["reading", "running"]
}

4.6 条件验证

{
  "$id": "https://example.com/conditional-validation-dependentRequired.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Conditional Validation with dependentRequired",
  "type": "object",
  "properties": {
    "foo": {
      "type": "boolean"
    },
    "bar": {
      "type": "string"
    }
  },
  "dependentRequired": {
    "foo": ["bar"]
  }
}
{
  "$id": "https://example.com/conditional-validation-dependentSchemas.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Conditional Validation with dependentSchemas",
  "type": "object",
  "properties": {
    "foo": {
      "type": "boolean"
    },
    "propertiesCount": {
      "type": "integer",
      "minimum": 0
    }
  },
  "dependentSchemas": {
    "foo": {
      "required": ["propertiesCount"],
      "properties": {
        "propertiesCount": {
          "minimum": 7
        }
      }
    }
  }
}
{
  "$id": "https://example.com/conditional-validation-if-else.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Conditional Validation with If-Else",
  "type": "object",
  "properties": {
    "isMember": {
      "type": "boolean"
    },
    "membershipNumber": {
      "type": "string"
    }
  },
  "required": ["isMember"],
  "if": {
    "properties": {
      "isMember": {
        "const": true
      }
    }
  },
  "then": {
    "properties": {
      "membershipNumber": {
        "type": "string",
        "minLength": 10,
        "maxLength": 10
      }
    }
  },
  "else": {
    "properties": {
      "membershipNumber": {
        "type": "string",
        "minLength": 15
      }
    }
  }
}

5. 验证器

JS 可运用 ajv:

离别繁琐的数据校验:用JSON Schema简化你的代码

// or ESM/TypeScript import
import Ajv from "ajv";
// Node.js require:
const Ajv = require("ajv");
const ajv = new Ajv(); // options can be passed, e.g. {allErrors: true}
const schema = {
  type: "object",
  properties: {
    foo: { type: "integer" },
    bar: { type: "string" },
  },
  required: ["foo"],
  additionalProperties: false,
};
const data = {
  foo: 1,
  bar: "abc",
};
const validate = ajv.compile(schema);
const valid = validate(data);
if (!valid) console.log(validate.errors);

其他渠道可参考官网:

离别繁琐的数据校验:用JSON Schema简化你的代码


微信查找“好朋友乐平”重视大众号。

github原文地址