处理复杂的结构化数据时,需要确定数据是否有效。 JSON-Schema是JSON文档的标准,描述了JSON数据的结构和要求。 在这个由两部分组成的系列文章中,您将学习如何使用JSON-Schema来验证数据。
假设您有一个用户数据库,其中每个记录看起来都类似于此示例:
{
"id": 64209690,
"name": "Jane Smith",
"email": "jane.smith@gmail.com",
"phone": "07777 888 999",
"address": {
"street": "Flat 1, 188 High Street Kensington",
"postcode": "W8 5AA",
"city": "London",
"country": "United Kingdom"
},
"personal": {
"DOB": "1982-08-16",
"age": 33,
"gender": "female"
},
"connections": [
{
"id": "35434004285760",
"name": "John Doe",
"connType": "friend",
"since": "2014-03-25"
},
{
"id": 13418315,
"name": "James Smith",
"connType": "relative",
"relation": "husband",
"since": "2012-07-03"
}
],
"feeds": {
"news": true,
"sport": true,
"fashion": false
},
"createdAt": "2015-09-22T10:30:06.000Z"
}
我们要处理的问题是如何确定上述记录是否有效。
示例非常有用,但在描述数据要求时还不够。 JSON-Schema可以解决。 这是描述用户记录的可能模式之一:
{
"$schema": "https://json-schema.org/draft-04/schema#",
"id": "http://mynet.com/schemas/user.json#",
"title": "User",
"description": "User profile with connections",
"type": "object",
"properties": {
"id": {
"description": "positive integer or string of digits",
"type": ["string", "integer"],
"pattern": "^[1-9][0-9]*$",
"minimum": 1
},
"name": { "type": "string", "maxLength": 128 },
"email": { "type": "string", "format": "email" },
"phone": { "type": "string", "pattern": "^[0-9()\-\.\s]+$" },
"address": {
"type": "object",
"additionalProperties": { "type": "string" },
"maxProperties": 6,
"required": ["street", "postcode", "city", "country"]
},
"personal": {
"type": "object",
"properties": {
"DOB": { "type": "string", "format": "date" },
"age": { "type": "integer", "minimum": 13 },
"gender": { "enum": ["female", "male"] }
}
"required": ["DOB", "age"],
"additionalProperties": false
},
"connections": {
"type": "array",
"maxItems": 150,
"items": {
"title": "Connection",
"description": "User connection schema",
"type": "object",
"properties": {
"id": {
"type": ["string", "integer"],
"pattern": "^[1-9][0-9]*$",
"minimum": 1
},
"name": { "type": "string", "maxLength": 128 },
"since": { "type": "string", "format": "date" },
"connType": { "type": "string" },
"relation": {},
"close": {}
},
"oneOf": [
{
"properties": {
"connType": { "enum": ["relative"] },
"relation": { "type": "string" }
},
"dependencies": {
"relation": ["close"]
}
},
{
"properties": {
"connType": { "enum": ["friend", "colleague", "other"] },
"relation": { "not": {} },
"close": { "not": {} }
}
}
],
"required": ["id", "name", "since", "connType"],
"additionalProperties": false
}
},
"feeds": {
"title": "feeds",
"description": "Feeds user subscribes to",
"type": "object",
"patternProperties": {
"^[A-Za-z]+$": { "type": "boolean" }
},
"additionalProperties": false
},
"createdAt": { "type": "string", "format": "date-time" }
}
}
查看上面的架构及其描述的用户记录(根据该架构有效)。 这里有很多解释要做。
用于根据模式验证用户记录JavaScript代码可以是:
var Ajv = require('ajv');
var ajv = Ajv({allErrors: true});
var valid = ajv.validate(userSchema, userData);
if (valid) {
console.log('User data is valid');
} else {
console.log('User data is INVALID!');
console.log(ajv.errors);
}
或为了获得更好的性能:
var validate = ajv.compile(userSchema);
var valid = validate(userData);
if (!valid) console.log(validate.errors);
GitHub repo tutsplus-json-schema中提供了所有代码示例。 您也可以在浏览器中尝试一下 。
示例中使用的验证器Ajv是JavaScript最快的JSON-Schema验证器。 我创建了它,因此在本教程中将使用它。
在继续之前,让我们快速处理所有原因。
为什么要单独验证数据?
- 快速失败
- 避免数据损坏
- 简化处理代码
- 在测试中使用验证码
为什么要使用JSON(而不是XML)?
- 与XML一