Basic Types

JSON Documents can be either basic values (strings, numbers, integers, the boolean constants or null), or ordered or unordered list of key:value pairs. We can use JSON Schema to specify that documents can be any of these. For now we concentrate on the specification for values. There are five basic value types supported by JSON Schema:

## String Schemas

One of the most basic forms of values that appear in JSON documents are strings of text. In JSON schema we can specify that a document is a string by using the keyword `string`

as the value of the name `type`

. That is, the document

`{"type": "string"}`

is a JSON Schema that valiadates against any JSON that is a string. Note that a JSON document is a string only if it is a sequence of Unicode characters enclosed in double quotation marks. That is, `"I am a string"`

is a valid JSON document that satisfies the above schema, but so is the sequence `"42"`

, or `"true"`

. On the other hand
`42`

is a JSON document that will *not* satisfy the above schema, and neither will the document `true`

.

### Restrictions

In order to control the length of our string we can use the keywords `minLength`

and `maxLength`

. To restrict the shape of the string even further we can specify that it conforms to a regular expression using the keyword `pattern`

.

#### Restricting the length of a string

We use the `"minLength"`

and `"maxLength"`

keywords to specify that the length of a string has to fall into a particular interval. For instance, the following schema

```
{
"type": "string",
"minLength": 3,
"maxLength": 7
}
```

specifies that our JSON document is a string whose minimum length is 3 and whose maximum length is 7. The keywords `"minLength"`

and `"maxLength"`

always have a non-negative integer as their value. The document `"This is"`

will validate against the above schema, as it is of length seven. On the other hand `"Is"`

, or `"This is not valid"`

will not validate against the schema, as the former is too short, while the latter is too long.

#### Regular expressions

To specify that a string conforms to a regular expression we use the keyword `"pattern"`

. For instance, if we want to enforce that the string is a valid email address with the extension `gmail.com`

that contains only letters of the alphabet, we could use the following JSON Schema.

```
{
"type": "string",
"pattern": "^[A-Za-z]*@gmail.com$"
}
```

Here we are specifying that the email address must end with `@gmail.com`

, while the part `[A-Za-z]*`

allows any string consisting of either lower or upper case characters. The symbols `^`

and `$`

are used to signify that the matching of a regular expression is done against the entire string. Therefore, the document `"adam@gmail.com"`

validates against the schema above, but `"g42s@gmail.com"`

does not validate, as the first part before the @ contains a character that is not a letter.

For a more detailed introduction to regular expressions we refer the reader to check out the RegexOne website.

### Formal Specification

String Schemas **strSch** are formally specified using the following grammar.

strSch:= "type": "string" (,strRes)^{*}strRes:=minLen|maxLen|patternminLen:= "minLength":nmaxLen:= "maxLength":npattern:= "pattern":regExp

where each **strRes** token appears at most once in **strSch**, n is an arbitrary non-negative integer and r is a regular expression as specified in RegexOne website.

### Formal Validation

Let **S** be a String Schema and **J** a JSON document. We say that **J** validates against **S** if for each key:value pair **k** in **S** one of the following holds:

**k**is`"type":"string"`

and**J**is a string**k**is of the form`"minLength" : n`

and**J**is a string of length at least**n****k**is of the form`"maxLength" : n`

and**J**is a string of length at most**n****k**is of the form`"pattern" : "rexp"`

and**J**is a string that matches the regular expression**rexp**

Note that in the formal definition we don not enforce the keyword `type`

to be specified. For instance the Schema

```
{
"minLength": 3,
"maxLength": 7
}
```

is well specified and will match any string whose length is between three and seven characters. This is a consequence of the fact that in the absence of explicit type definition we can still infer the base type by parsing other keywords. This behavior is specified in the `multiple type`

schemas section. We would, however, like to stress that explicitly specifying the type is a good practice that should always be adhered to.

## Numeric Schemas

Another form of value in JSON are numbers. In JSON Schema we can
specify that a document must be a number by using the `type`

keyword. The document

`{"type": "number"}`

is a JSON Schema, and validates against any numeric value. For example, values `34`

and `1.82`

satisfy `{"type": "number"}`

, while `"34"`

does not, because it is a string.

If we need to specify that a value must be an integer, we use instead the keyword `integer`

:

`{"type": "integer"}`

Now the value `34`

satisfies this schema, but `1.82`

does not.

### Restrictions

We can also specify additional constraints that the numbers must satisfy. All of these keywords can be use by either `number`

or `integer`

types.

#### Range

Suppose we need to specify a value for the age of a person, and we want it to be an integer between 0 and 150. We use the
`"minimum"`

and `"maximum"`

keywords:

```
{
"type": "integer",
"minimum": 0,
"maximum": 150
}
```

This document validates against any number between `0`

and `150`

.
By default the ranges are inclusive: `"minimum": n`

imposes the restriction that numbers need to be *greater than or equal to* `n`

, and `"minimum": m`

imposes that numbers need to be *less than or equal to* `m`

. This means that both `0`

and `150`

satisfy the schema above. We can switch the ranges to be exclusive by using the `"exclusiveMinimum"`

and `"exclusiveMaximum"`

keywords.

For example, the following schema validates against `0`

, but not against `150`

:

```
{
"type":"integer",
"minimum": 0,
"maximum": 150,
"exclusiveMaximum":true
}
```

If the `"minimum": n`

keyword is present together with the keyword `"exclusiveMinimum":true`

then the restriction imposes that numbers must be *greater* than `n`

, and if the `"maximum": m`

keyword is present together with `"exclusiveMaximum":true`

then the restriction is that the number must be *lower than* `m`

.

#### Multiplicity

We can also specify that a number must be the multiple of another number, as in the following schema:

```
{
"type": "integer",
"multipleOf": 10
}
```

This schema validates against any number that is a multiple of `10`

.
Note that we can also use real numbers in `"multipleOf"`

, and we can combine it with range restrictions. For example, the schema
```
{
"type":"integer",
"multipleOf": 3.3,
"maximum": 7
}
```

validates against numbers `3.3`

and `6.6`

.

### Formal Specification

Numeric schemas **numSch** are constructed using the following grammar:

numSch:= "type": ("number" | "integer") (,numRes)^{*}numRes:=min|max|multiplemin:= "minimum":r(,exMin)?exMin:= "exclusiveMinimum":boolmax:= "maximum":r(,exMax)?exMax:= "exclusiveMaximum":boolmultiple:= "multipleOf":r(r≥0)

where each **numSch** can have at most one of each **min**, **max** and **multiple**. Here **r** is any positive decimal number, and **bool** is either **true** or **false**.

### Validation

Let **N** be a numeric schema and **J** a JSON document. Then **N** validates against **J** if for each name/value pair **k** in **N**, one of the following holds:

**k**is`"type":"number"`

and**J**is a number.**k**is`"type":"integer"`

and**J**is an integer number (a number without the decimal`.`

marker).**k**is`"multipleOf": r`

for some positive decimal number**r**, and**J**is a number that is a multpiple of**r**.**k**is`"minimum": r`

for some decimal**r**, and**J**is a number that is strictly greater than**r**.**k**is`"minimum": r`

for some decimal**r**,**J**is a number that is equal to**r**and the pair`"exclusiveMinimum": true`

is not in**N**.**k**is`"maximum": r`

, for some decimal**r**, and**J**is a number that is stricly less than**r**.**k**is`"maximum": r`

for some decimal**r**,**J**is a number that is equal to**r**and the pair`"exclusiveMinimum": true`

is not in**N**.

## Boolean Schemas

In order to specify a property that can be either true or false we use the value type `boolean`

. A JSON Schema specifying the type `boolean`

is given below.

`{"type": "boolean"}`

This schema will validate only aginst JSON documents `true`

and `false`

. Any document of diferent form or of different type, such as `"true"`

, `42`

, or `"Number"`

, will not satsfy the schema. Note that values that usually evaluate to boolean values in programming languages, such as `0`

and `1`

are also not permitted.

### Formal Specification

A Boolean Schema **boolSch** is formally specified using the following grammar.

boolSch:= "type": "boolean"

### Formal Validation

Let **B** be a Boolean Schema and **J** a JSON document. We say that **J** validates against **B** if:

**J**is either**true**or**false**

## Null Schemas

When specifying that a certain value is missing it is usual to use the type `null`

. A JSON Schema specifying null values is given below.

`{"type": "null"}`

This schema will validate aginst JSON document `null`

and reject all other JSON documents. Therefore documents such as `"false"`

, `false`

or `0`

will not validate against the schema above.

### Formal Specification

A Schema **nullSch** for `null`

values is formally specified using the following grammar.

boolSch:= "type": "null"

### Formal Validation

Let **N** be a Schema for `null`

values and **J** a JSON document. We say that **J** validates against **N** if:

**J**equals**null**