Article introduction:
Introducing json-schema in the vernacular, from basic concepts to high-level usage, from the shallower to the deeper, combined with practical applications to analyze the actual role of json-schema.
1. Origin
What is json-schema?
Before answering this question, let's first understand the background of it.
With the development of the Internet, front-end and back-end interaction, from the original text/html, image/* picture and other file streams, to the current application/x-www-form-urlencoded, multipart/form-data, application/json stream, and Future application/octet-stream binary. But there is no doubt that the most popular format for front-end and back-end interaction is application/json, which is also the most used format in the development process of our developers.
In addition, the application of json in the front-end is becoming more and more important. No matter how it develops in the future, it will always have an indispensable and important position. Why? The author believes that the most fundamental reason is that it is essentially an object. Today, object-oriented programming is rampant. Naturally, its dominance cannot be shaken. At the same time, its light weight, high readability, strong expansion, and high transmission efficiency are also An important reason is that it is playing an important media role for the interaction between humans and machines.
It is precisely because json is used more and more widely, and the tools related to it are born, and json-schema is one of them.
Suppose we have such a JSON data format:
{
"id": "1432423230",
"name": "Jeck",
"sex": "male"
}
Although this json is simple and clear to developers, we can easily know that it is a string representing a Person, but there are still some problems, such as:
- Can id be a number?
- Is there any character limit for name?
- Is sex necessary? Can it be man and woman?
Perhaps the founder of the project will be very clear about the meaning of these fields. However, as the project grows, after a year, he may not be able to remember the meaning of these fields. As the initial developer of the code, if this is the case, then take over Not to mention other maintainers of the project.
Although we all know what the meaning of the above json code (Person) is, everyone’s understanding of the fields in it may be different. We can only understand its meaning based on the meaning of the attribute in English, but we cannot assume everyone’s English level. They are all very high, and the set attribute values can allow others to see what they mean at a glance.
Therefore, as the team is becoming more and more important today, it is very necessary to specify a set of json specifications for the team, so that the team understands it consistently, so as to achieve this goal:
- Reduce the cost of understanding;
- Improve development efficiency;
- Reduce maintenance costs.
Then come back and answer again what is json-schema? Believe that you are smart, you have guessed it.
Yes, yes, it is a set of specifications for json, and some people say that it is a tool for verifying json, and it is a proposed IETF standard...in fact, it is all meaning.
If you are familiar with typescript or flow , then you can quickly sort out this set of relationships:
json-schema is to json as typescript (or flow) is to javascript
2. Introduction
1) Basic types
The two basic types that make up JSON: Object and Array
The value of value is: string, number, object, array, boolean, null
tips: no undefined type
2) Basic concepts
Since it is a set of specifications, there will be a lot of semantics, so let's start with the simplest example, as follows:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/person.schema.json",
"title": "Person",
"description": "it is a person object",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a person",
"type": "string"
}
},
"required": [ "id" ]
}
Normally, the formats and properties we see most are type and properties, which are used to describe an object, and items are used to describe an array.
3) Define the attribute value
When id describes the unique symbol of a person, similar to our ID number, this is a unique identifier for this piece of data. It is a must for the database, and at the same time we limit its type to string.
The name is a symbol to describe people, which is closer to human usage habits. Computers usually pay attention to the identifier ID, and humans usually pay more attention to the name, so it is usually also necessary, and the maximum length is limited to 50.
description represents the description of the field, which makes people more understand what the attribute value wants to express.
type restricts the type of the field.
Required is a list of attributes required for verification. Not filling in means no verification. Sudden increase or decrease of the property will not be verified.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/person.schema.json",
"title": "Person",
"description": "it is a person object",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a person",
"type": "string"
},
"name": {
"description": "The identifier for a person",
"type": "string",
"maxLength": 50
}
},
"required": [ "id", "name" ]
}
4) In-depth understanding of attributes
At the same time, we need to regulate gender, otherwise, for men with the same meaning, one person will be understood as male and the other as man.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/person.schema.json",
"title": "Person",
"description": "it is a person object",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a person",
"type": "string"
},
"name": {
"description": "The identifier for a person",
"type": "string",
"maxLength": 50
},
"sex": {
"description": "The gender of the person",
"type": "string",
"enum": ["male", "female"]
},
},
"required": [ "id", "name" ]
}
Suddenly one day, the demand changed, and the product manager said that another attribute age should be added. The age should not be less than 0, let alone more than 1000~
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/person.schema.json",
"title": "Person",
"description": "it is a person object",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a person",
"type": "string"
},
"name": {
"description": "The identifier for a person",
"type": "string",
"maxLength": 50
},
"sex": {
"description": "The gender of the person",
"type": "string",
"enum": ["male", "female"]
},
"age": {
"description": "The age for a person",
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000
}
},
"required": [ "id", "name" ]
}
Among them, exclusiveMinimum means greater than. If we want to include 0 as the effective age, we will specify minimum as the keyword, which means greater than or equal to. Correspondingly, maximum and exclusiveMaximum are respectively less than or equal to and less than.
Knowing the name and age of a person, it seems that there is something missing. Just imagine, after you meet a handsome guy or a beautiful woman, you are lucky that you successfully got on the conversation and you had a good time talking, then you will be the last parting. What is a very important thing?
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/person.schema.json",
"title": "Person",
"description": "it is a person object",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a person",
"type": "string"
},
"name": {
"description": "The identifier for a person",
"type": "string",
"maxLength": 50
},
"sex": {
"description": "The gender of the person",
"type": "string",
"enum": ["male", "female"]
},
"age": {
"description": "The age for a person",
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000
},
"phone": {
"description": "The contact for a person",
"type": "string",
"pattern": "^[13|14|15|16|17|18|19][0-9]{9}$"
}
},
"required": [ "id", "name" ]
}
String constraints support the description of regular expressions, using the pattern keyword.
With the rise of the post-90s and 00s, they are a group of people with dreams and self-pursuing, so they will pay more and more attention to their own personality and label, and our initial project did not have this content field.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/person.schema.json",
"title": "Person",
"description": "it is a person object",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a person",
"type": "string"
},
"name": {
"description": "The identifier for a person",
"type": "string",
"maxLength": 50
},
"sex": {
"description": "The gender of the person",
"type": "string",
"enum": ["male", "female"]
},
"age": {
"description": "The age for a person",
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000
},
"phone": {
"description": "The contact for a person",
"type": "string",
"pattern": "^[13|14|15|16|17|18|19][0-9]{9}$"
},
"tags": {
"description": "The labels to describe a person",
"type": "array",
"items": [
{ "type": "string" }
],
"minItems": 1,
"uniqueItems": true
},
},
"required": [ "id", "name" ]
}
The introduction of items specifies that each item in the array requires that the content in the array is of string type. At the same time, if this field tags is declared, then minItems specifies that it has at least one tag, and uniqueItems specifies that each tag is unique.
5) Nested structure
The data we usually encounter is not flat, and the hierarchy is generally deeper. Here we introduce an address field to it.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/person.schema.json",
"title": "Person",
"description": "it is a person object",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a person",
"type": "string"
},
"name": {
"description": "The identifier for a person",
"type": "string",
"maxLength": 50
},
"sex": {
"description": "The gender of the person",
"type": "string",
"enum": ["male", "female"]
},
"age": {
"description": "The age for a person",
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000
},
"phone": {
"description": "The contact for a person",
"type": "string",
"pattern": "^[13|14|15|16|17|18|19][0-9]{9}$"
},
"tags": {
"description": "The labels to describe a person",
"type": "array",
"items": [
{ "type": "string" }
],
"minItems": 1,
"uniqueItems": true
},
"address": {
"description": "The address for a person",
"type": "object",
"properties": {
"country": {
"type": "string"
},
"province": {
"type": "string"
},
"city": {
"type": "string"
},
"region": {
"type": "string"
},
"detail": {
"type": "string"
}
},
"required": ["country", province", "city", "region"]
},
},
"required": [ "id", "name" ]
}
Finally, let's take a look at what the json we defined should look like.
{
"id": "A000000000",
"name": "溥仪",
"sex": "male",
"age": 112,
"phone": "1300000000",
"tags": ["吃饭","睡觉","发呆","末代皇帝"],
"address": {
"country": "天朝",
"province": "帝都",
"city": "帝都",
"region": "东城区",
"detail": "景山前街4号故宫博物馆",
}
}
For more property specifications, please go to the official website: https://json-schema.org/draft/2019-09/json-schema-validation.html
Three, high-level usage
1) Reuse
As large as a spaceship, as small as a mobile phone for daily use, many trouble-saving things in this world are created just because of laziness. The cute siege lions are also such a group of intelligent animals. We just want to write many programs, such as the address definition above. There is a scenario where a person’s address can have many types, such as receiving address and sending address. They may include school address, company address, home address, and renting a house. Address and so on. And their structures are the same, so we can't define so much address information repeatedly, and json-schema also supports this operation.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"address": {
"type": "object",
"properties": {
"country": {
"type": "string"
},
"province": {
"type": "string"
},
"city": {
"type": "string"
},
"region": {
"type": "string"
},
"detail": {
"type": "string"
}
},
"required": ["country", province", "city", "region"]
},
},
"type": "object",
"properties": {
"receipt_address": {
"#ref": "#/definitions/address"
},
"send_address": {
"#ref": "#/definitions/address"
}
}
}
Or combine $id and $ref for reference processing.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"address": {
"$id": "#address",
"type": "object",
"properties": {
"country": {
"type": "string"
},
"province": {
"type": "string"
},
"city": {
"type": "string"
},
"region": {
"type": "string"
},
"detail": {
"type": "string"
}
},
"required": ["country", province", "city", "region"]
},
},
"type": "object",
"properties": {
"receipt_address": {
"#ref": "#address"
},
"send_address": {
"#ref": "#address"
}
}
}
2) Recursion
From the above, we know that using $ref can handle shared problems, then can we further understand that we can call ourselves, and then form recursion? yes, we can!
The most common is the dom structure of html, which itself uses recursion to generate dom, for example:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"element": {
"$id": "#element",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"props": {
"type": "object",
"properties": {},
},
"children": {
"type": "array",
"items": {"$ref": "#element"},
},
}
},
},
"type": "object",
"properties": {
"element": {
"#ref": "#element"
}
}
}
It should be noted that when calling recursively, do not refer to each other between a and b, otherwise an infinite loop will be formed.
Four, practical application
Considering the network bandwidth and development efficiency, we usually omit a lot in actual applications. Some of the above descriptions will appear redundant. Let us look at an actual application. Take @formily/antd as an example.
The json-schema corresponding to the above inline layout is:
{
"type": "object",
"properties": {
"aaa": {
"key": "aaa",
"name": "aaa",
"type": "string",
"title": "字段1",
"x-component": "input"
},
"bbb": {
"key": "bbb",
"name": "bbb",
"type": "number",
"title": "字段2",
"x-component": "numberpicker"
},
"ccc": {
"key": "ccc",
"name": "ccc",
"type": "date",
"title": "字段3",
"x-component": "datepicker"
}
}
}
The above type specifies what the input value type of the attribute value should be. By comparison, you will find that only the json-schema data used for verification is.
{
"type": "object",
"properties": {
"aaa": {
"type": "string",
},
"bbb": {
"type": "number",
},
"ccc": {
"type": "date",
}
}
}
tips: The above "type":"date" is a new type added to draft7.
In the actual application of @formily/antd, the verification attributes and business attributes are mixed together. Strictly speaking, it is not a standard json-schema. It has developed a set of its own json-schema combined with its actual business. schema, you can understand it as pseudo json-schema, but it is worth learning from and learning.
Under normal circumstances, we can also actively verify the legitimacy of the json we write by using third-party tools, such as jsonschema, and react-jsonschema-form.
Five, summary
Today, I only introduced some basic usages of json-schema, which is just the tip of the iceberg. It also has many powerful functions, such as dependencies, additionalItems, consts, allOf, anyOf, oneOf, not, if……then……else, etc. Wait, for more ways to play, you can go to json-schema official website .
Finally, let us summarize the basic knowledge of json-schema, which is a set of specifications for verifying json, and a set of rules for both reading and writing to follow at the same time.
From small to large, let's disassemble json-schema, so what is a schema?
The definition given by Wikipedia is:
The word schema comes from the Greek word σχῆμα (skhēma), which means shape, or more generally, plan.
Strictly speaking, a schema is a kind of architecture or mode, a structure described by a formal language in a database system, and a collection of objects.
By analogy, there will be xml-schema, yaml-schema... They all refer to a specification and mode of XXX data.
reference
- json-schema official website: https://json-schema.org/
- json-schema use tutorial document: http://xaber.co/2015/10/20/JSON-schema-use tutorial document/
- @formily/antd's SchemaForm: https://formilyjs.org/#/0yTeT0/jbUzUluaIG
Text|Alan
Pay attention to Dewu Technology, and work hand in hand to the cloud of technology
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。