Section id
- An identifier:
productId - A product name:
productName - A selling cost for the consumer:
price - An optional set of tags:
tags.
For example:
{
"productId": 1,
"productName": "A green door",
"price": 12.50,
"tags": [ "home", "green" ]
}
While generally straightforward, the example leaves some open questions. Here are just a few of them:
- What is
productId? - Is
productNamerequired? - Can the
pricebe zero (0)? - Are all of the
tagsstring values?
When you’re talking about a data format, you want to have metadata about what keys mean, including the valid inputs for those keys. JSON Schema is a proposed IETF standard how to answer those questions for data.
Yes. the standard uses a JSON data document to describe data documents, most often that are also JSON data documents but could be in any number of other content types like text/xml.
- The
$schemakeyword states that this schema is written according to a specific draft of the standard and used for a variety of reasons, primarily version control. - The
$idkeyword defines a URI for the schema, and the base URI that other URI references within the schema are resolved against. - The
titleanddescriptionannotation keywords are descriptive only. They do not add constraints to the data being validated. The intent of the schema is stated with these two keywords. - The
typevalidation keyword defines the first constraint on our JSON data and in this case it has to be a JSON Object.
{
"$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"
}We introduce the following pieces of terminology when we start the schema:
- Schema Keyword:
$schemaand$id. - Schema Annotations:
titleanddescription. - Validation Keyword:
type.
Defining the properties #
productId is a numeric value that uniquely identifies a product. Since this is the canonical identifier for a product, it doesn’t make sense to have a product without one, so it is required.
In JSON Schema terms, we update our schema to add:
- The
propertiesvalidation keyword. - The
productIdkey.descriptionschema annotation andtypevalidation keyword is noted – we covered both of these in the previous section.
- The
requiredvalidation keyword listingproductId.
{
"$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" ]
}productNameis a string value that describes a product. Since there isn’t much to a product without a name it also is required.- Since the
requiredvalidation keyword is an array of strings we can note multiple keys as required; We now includeproductName. - There isn’t really any difference between
productIdandproductName– we include both for completeness since computers typically pay attention to identifiers and humans typically pay attention to names.
{
"$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" ]
}Going deeper with properties #
According to the store owner there are no free products. ;)
- The
pricekey is added with the usualdescriptionschema annotation andtypevalidation keywords covered previously. It is also included in the array of keys defined by therequiredvalidation keyword. - We specify the value of
pricemust be something other than zero using theexclusiveMinimumvalidation keyword.- If we wanted to include zero as a valid price we would have specified the
minimumvalidation keyword.
- If we wanted to include zero as a valid price we would have specified the
{
"$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" ]
}- The
tagskey is added with the usual annotations and keywords. - This time the
typevalidation keyword isarray. - We introduce the
itemsvalidation keyword so we can define what appears in the array. In this case:stringvalues via thetypevalidation keyword. - The
minItemsvalidation keyword is used to make sure there is at least one item in the array. - The
uniqueItemsvalidation keyword notes all of the items in the array must be unique relative to one another. - We did not add this key to the
requiredvalidation keyword array because it is optional.
{
"$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" ]
}Nesting data structures #
Up until this point we’ve been dealing with a very flat schema – only one level. This section demonstrates nested data structures.
- The
dimensionskey is added using the concepts we’ve previously discovered. Since thetypevalidation keyword isobjectwe can use thepropertiesvalidation keyword to define a nested data structure.- We omitted the
descriptionannotation keyword for brevity in the example. While it’s usually preferable to annotate thoroughly in this case the structure and key names are fairly familiar to most developers.
- We omitted the
- You will note the scope of the
requiredvalidation keyword is applicable to the dimensions key and not beyond.
{
"$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" ]
}References outside the schema #
So far our JSON schema has been wholly self contained. It is very common to share JSON schema across many data structures for reuse, readability and maintainability among other reasons.
For this example we introduce a new JSON Schema resource and for both properties therein:
- We use the
minimumvalidation keyword noted earlier. - We add the
maximumvalidation keyword. - Combined, these give us a range to use in validation.
{
"$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" ]
}Taking a look at data for our defined JSON Schema #
We’ve certainly expanded on the concept of a product since our earliest sample data (scroll up to the top). Let’s take a look at data which matches the JSON Schema we have defined
{
"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
}
}https://developers.google.com/business-communications/business-messages/reference/rest/#service-endpoint
Comments
Post a Comment
We are open to discuss for the best Learn more how to optimize our business on our website? Please give a short line advice.