JCR Tutorial

JSON Content Rules (JCR) is a language for describing and testing the interchange of data in JSON [RFC7159] format used by computer protocols and processes. The syntax of JCR is not JSON but is "JSON-like", possessing the conciseness and utility that has made JSON popular.

As an example, the following JSON is taken from RFC 7159:

{
    "Image": {
        "Width":  800,
        "Height": 600,
        "Title":  "View from 15th Floor",
        "Thumbnail": {
            "Url":    "http://www.example.com/image/481989943",
            "Height": 125,
            "Width":  100
        },
    "Animated" : false,
    "IDs": [116, 943, 234, 38793]
    }
}

It can be described using JCR as:

{
    "Image" : {
        "Width" : 0..1280,
        "Height" : 0..1024,
        "Title" : string,
        "Thumbnail" : {
            "Url" : uri,
            "Width" : 0..1280,
            "Height" : 0..1024
        },
        "Animated" : boolean,
        "IDs" : [ integer * ]
    }
}

In the above, the sub-rules "Width" : 0..1280 and "Height" : 0..1024 are repeated multiple times. To make this simpler and easier to manage, each can be defined in their own named rule, and the rule name can be used in place of the sub-rules; giving:

{
    "Image" : {
        $width,
        $height,
        "Title" : string,
        "Thumbnail" : {
            "Url" : uri,
            $width,
            $height
        },
        "Animated" : boolean,
        "IDs" : [ integer * ]
    }
}

$width = "Width" : 0..1280
$height = "Height" : 0..1024

As $width and $height are often used together, the above can be further simplified by putting them in a group and using the group as a mixin. Below, this is done in the group named $dimensions:

{
    "Image" : {
        $dimensions,
        "Title" : string,
        "Thumbnail" : {
            "Url" : uri,
            $dimensions
        },
        "Animated" : boolean,
        "IDs" : [ integer * ]
    }
}

$dimensions = ( $width, $height )
$width = "Width" : 0..1280
$height = "Height" : 0..1024

Rules can also be used to specify types. For example, below the integer type in the "IDs" object member is replaced by $id:

{
    "Image" : {
        $dimensions,
        "Title" : string,
        "Thumbnail" : {
            "Url" : uri,
            $dimensions
        },
        "Animated" : boolean,
        "IDs" : [ $id * ]
    }
}

$dimensions = ( $width, $height )
$width = "Width" : 0..1280
$height = "Height" : 0..1024
$id = integer

Or, perhaps the entire "Thumbnail" member could be extracted into a separate rule:

{
    "Image" : {
        $dimensions,
        "Title" : string,
        $thumbnail,
        "Animated" : boolean,
        "IDs" : [ $id * ]
    }
}

$thumbnail =
    "Thumbnail" : {
        "Url" : uri,
        $dimensions
    }

$dimensions = ( $width, $height )
$width = "Width" : 0..1280
$height = "Height" : 0..1024
$id = integer

If the "Thumbnail" member was optional, this can be indicated using the Kleene ? operator:

{
    "Image" : {
        $dimensions,
        "Title" : string,
        $thumbnail ?,
        "Animated" : boolean,
        "IDs" : [ $id * ]
    }
}

$thumbnail =
    "Thumbnail" : {
        "Url" : uri,
        $dimensions
    }

$dimensions = ( $width, $height )
$width = "Width" : 0..1280
$height = "Height" : 0..1024
$id = integer

JCR allows modular message specification using #import directives. As screen and image dimensions might be a common, cross-protocol feature, they can be separated into a separate module. Such a module would be incorporated into the example as:

#import org.ietf.geometry as geometry

{
    "Image" : {
        $geometry.dimensions,
        "Title" : string,
        $thumbnail ?,
        "Animated" : boolean,
        "IDs" : [ $id * ]
    }
}

$thumbnail =
    "Thumbnail" : {
        "Url" : uri,
        $geometry.dimensions
    }

$id = integer

Where org.ietf.geometry might be defined as:

#ruleset-id org.ietf.geometry

$dimensions = ( $width, $height )
$width = "Width" : 0..1280
$height = "Height" : 0..1024

JCR has many more features to help protocol and software developers. Have a look at the specification to find out more.