JSchema

"Simplicity is a prerequisite for reliability."

See also jschema-rpc

Introduction

The great virtue of JSON is that it is simple. Its grammar consists of 15 productions, making it both easy to parse and produce.

A simple data interchange format demands a simple schema mechanism. The current schema standard, JSON Schema, does not satisfy this requirement.

JSchema fills this gap. The design goals of JSchema are:

In order to retain simplicity it is necessary to forego some features. JSchema does not support:

Schema URL and File Conventions

Assuming JSON content matching a given JSchema is available at

http://example.com/path/
then the JSchema should be available at
http://example.com/path/?JSchema

Locally, JSchema files should end with the .jsc file suffix.

Grammar

A JSchema document is a valid JSON document conforming to the following grammar:

<type> ::= 
    <core_types> |
    <array_type> |
    <enum_type> |
    <map_type> |
    <struct_type> |
    <string>

<core_types> ::=
    '"string"' |
    '"boolean"' |
    '"date"' |
    '"uri"' |
    '"int"' |
    '"number"' |
    '"self"' |
    '"object"'

<array_type> ::= 
    '[' type ']'

<enum_type> ::= 
    '{' '"enum"' ':' '[' <enum_values> ']' '}'

<enum_values> ::=
    string
    string ',' <enum_values>

<map_type> ::=
    '{' '"map_of"' ':' <type> '}'

<struct_type> ::= 
    '{' <typedefs_and_props> '}'

<typedefs_and_props> ::= 
    <typedefs_map> ',' <props> |
    <props> |

<typedefs_map> ::= 
    '"typedefs@"' ':' '{' <type_defs> '}'

<type_defs> ::= 
    <type_def> |
    <type_def> ',' <type_defs>

<type_def> ::=
    <string> ':' <type_def_type>

<type_def_type> ::= 
    <struct_type> |
    <enum_type>

<props> ::= 
    <prop> |
    <prop> ',' <props>

<prop> ::= 
    <string> ':' <type>
    

Types

"string"

A string may be a JSON string.

"boolean"

A boolean may have a value of 'true' or 'false', sans quotes.

"date"

A date may be a JSON string in any format specified by the W3C NOTE-datetime.

"uri"

A uri may be a JSON string that is a valid URI.

"int"

An int may be a JSON int.

"number"

A number may be a JSON number.

"self"

"self" refers to the schema defined by the current JSchema file.

"object"

An object may be an arbitrary JSON object.

Array Type

An array may be a JSON Array with elements that conform to the type definition enclosed within the array.

Enum Type

An enum must have a JSON string value from domain specified in the array on the right hand side.

Map Type

A map may be a JSON object with an arbitrary number of members, where the name of the pair can be a JSON string, and the value must satisfy the right hand type definition.

Struct Type

A struct type defines a JSON object by a series of name/type pairs. For each name/type pair, a conforming JSON object, if a pair with the name is present, will have a value conforming to the type. If the name is not present, it is interpreted as being null. Additionally, pairs not mentioned in the Struct Type may be present and should be preserved at runtime for re-serialization.

Struct TypeDefs

A struct type may define types to refer to by name using the 'typedef@' syntax. A typedef consists of a string name and a type definition. The name of each typedef must be unique and not conflict with the core type names. Typedef names are valid within the context of the struct type they are defined in.

Typedefs may be either Struct Types or Enum Types.

Nullability

All values in a JSON document described by a JSchema schema may have a null value. The interpretation of the null value is left to implementations, with the caveat that null should be preserved for re-serialization.

Comments

JSchema implementations are required to accept c-style comments in JSchema files.

Examples

Schema Examples
{ "name" : "string", "age" : "int" } { "name" : "Joe", "age" : 42 }
{ "people" : [ { "name" : "string", "age" : "int"} ] } { "people" : [ { "name" : "Joe", "age" : 42 } { "name" : "Paul", "age" : 28 } { "name" : "Mack", "age" : 55 } ] }
{ "people" : [ { "name" : "string", "age" : "int", "eye_color" : {"enum" : ["brown", "blue", "green"]}} ] } { "people" : [ { "name" : "Joe", "age" : 42, "eye_color" : "brown" }, { "name" : "Paul", "age" : 28, "eye_color" : "brown" }, { "name" : "Mack", "age" : 55, "eye_color" : "blue" } ] }
{ "id_to_people" : { "map_of" : { "name" : "string", "age" : "int", "eye_color" : {"enum" : ["brown", "blue", "green"]} } } } { "id_to_people" : { "1" : { "name" : "Joe", "age" : 42, "eye_color" : "brown" }, "2" : { "name" : "Paul", "age" : 28, "eye_color" : "brown" }, "3" : { "name" : "Mack", "age" : 55, "eye_color" : "blue" } } }