Skip to main content

JSON Schema Tips

Metadata

You should use the title and description keywords to provide a description of the schema. This will help users understand what the schema is for.

{
"title": "My Schema",
"description": "This is a schema for my app"
}

Examples

You can provide examples of how the schema should be used by using the examples keyword.

{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"examples": {
"name": "John Doe"
}
}

Comments

You can use the $comment keyword to provide comments in the schema. This can be useful for providing additional information about the schema.

{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"$comment": "This is a schema for my app"
}

For more information check the relevant JSON Schema Docs

Default

When you have a default value for a property, you can use the default keyword to set it. This is useful for when you want to provide a default value for a property that is not required.

{
"type": "object",
"properties": {
"name": {
"type": "string",
"default": "John Doe"
}
}
}

The value will be provided by the config even if it is not set.

Required

You can use the required keyword to specify which properties are required in the schema. By default, all properties are optional.

{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": ["name"]
}

The types generated for the schema will reflect the required properties.

type MySchema = {
name: string;
};

Enums

You can use the enum keyword to specify a list of possible values for a property. It is not required to specify the type of the property when using enum, so its possible for the enum to be of different types.

{
"type": "object",
"properties": {
"color": {
"enum": ["red", "green", "blue"]
}
}
}

The types generated will be a union of the enum values.

type MySchema = {
color: "red" | "green" | "blue";
};

Refs

You can use the $ref keyword to reference another schema. The references can be either internal or external.

Reference can be used to reuse schemas and keep the schema definitions clean. Even for small schemas like Id, it is a good practice to use refs.

Internal Refs

{
"type": "object",
"properties": {
"name": {
"$ref": "#/definitions/name"
}
},
"definitions": {
"name": {
"type": "string"
}
}
}

External Refs

External refs are only valid to other schemas that are defined in the schemas repository. The way to reference is to use the ID of required the schema.

{
"type": "object",
"properties": {
"name": {
"$ref": "https://mapcolonies.com/common/schema/v1"
}
}
}

Definitions

You can use the definitions keyword to define reusable schemas. The definitions are not part of the validated schema, unless they are referenced.

{
"type": "object",
"properties": {
"name": {
"$ref": "#/definitions/name"
}
},
"definitions": {
"name": {
"type": "string"
}
}
}

Schema Composition

In many cases you will want to compose multiple schemas together. JSON Schema provides a few keywords to help with this. This way you can reuse schemas and keep the schema definitions clean.

The classic example in our case is to extends the boilerplate schema to fit our service.

For more information check the relevant JSON Schema Docs

AllOf

The allOf keyword is used to combine multiple schemas together. The properties of the schemas are merged together.

The following schema

{
"allOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
{
"type": "object",
"properties": {
"age": {
"type": "number"
}
}
}
]
}

Will be equivalent to the following schema

{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
}
}
}
important

When using additionalProperties: false in the schemas, the allOf keyword will not merge the properties together. Instead, it will require that all properties are present in the schema, Which is not possible. Check the JSON Schema Docs for more information.

OneOf

The oneOf keyword is used to specify that only one of the schemas should be valid.

The following schema

{
"oneOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
{
"type": "object",
"properties": {
"age": {
"type": "number"
}
}
}
]
}

If both properties are provided, the schema will be invalid.

Strings

Formats

It is recommended to use the format keyword to specify the format of the string. This will help users understand what the string is for and validate accordingly.

{
"type": "string",
"format": "email"
}

For a full list of formats check the ajv-formats repository.

Patterns

You can use the pattern keyword to specify a regular expression that the string should match.

{
"type": "string",
"pattern": "^[a-zA-Z]+$"
}

Const

You can use the const keyword to specify a constant value for the string.

{
"type": "string",
"const": "John Doe"
}