Skip to contents

The goal of rjsonschema is to validate JSON strings or objects against JSON schema definitions. For an introduction to JSON schemas, visit: https://json-schema.org/.

The package is a light wrapper around the jsonschema-rs (Github source) Rust crate.

Installation

You can install the development version of rjsonschema like so:

# DEV version
# remotes::install_github("DavZim/rjsonschema")

# CRAN version
install.packages("rjsonschema")

Usage Example

library(rjsonschema)

# 1. define a simple schema
schema <- '{"type": "string"}'

# 2. test the schema against JSON strings
# note '123' is a JSON string, which represents an integer and not a string!
validate(schema = schema, instance = '"hello world"') # passes as "hello" is a string
#> [1] TRUE
validate(schema = schema, instance = '123') # fails as 123 is not a string
#> [1] FALSE

# multiple instances work!
validate(schema = '{"type": "string"}', instance = c('"hello"', '123'))
#> [1]  TRUE FALSE

# get more information about the validation with style basic
validate(schema = '{"type": "string"}', instance = '123', style = "basic") |> 
  str()
#> List of 1
#>  $ :List of 2
#>   ..$ errors:List of 1
#>   .. ..$ :List of 3
#>   .. .. ..$ error           : chr "123 is not of type \"string\""
#>   .. .. ..$ instanceLocation: chr ""
#>   .. .. ..$ keywordLocation : chr "/type"
#>   ..$ valid : logi FALSE

validate(schema = '{"type": "string"}', instance = c('"hello"', '123'), style = "basic") |> 
  str()
#> List of 2
#>  $ :List of 2
#>   ..$ annotations: list()
#>   ..$ valid      : logi TRUE
#>  $ :List of 2
#>   ..$ errors:List of 1
#>   .. ..$ :List of 3
#>   .. .. ..$ error           : chr "123 is not of type \"string\""
#>   .. .. ..$ instanceLocation: chr ""
#>   .. .. ..$ keywordLocation : chr "/type"
#>   ..$ valid : logi FALSE

Note, both instance and schema can be JSON strings (as shown above), file names to JSON files, or R objects (mostly lists).

You can also validate a schema against a specific JSON meta schema (the JSON schema definition of a schema).

schema <- '{"type": "string"}'
# if you want to have a look at the meta scheme, see the following file:
# system.file("schema-draft202012.json", package = "rjsonschema") or
# <https://json-schema.org/draft/2020-12/schema>
validate_schema(schema, version = "draft202012")
#> [1] TRUE

If you want to use this function with stopifnot(), or similar assertion libraries, you can set err_on_invalid to TRUE:

validate(schema = '{"type": "string"}', instance = '123', err_on_invalid = TRUE)
#> Error in validate(schema = "{\"type\": \"string\"}", instance = "123", : '123 is not of type "string"' for field '/type'

Full Example

A longer example, taken from the official getting started guide, is the following. For a store, we are given the following schema, which defines a JSON for a product:

{
  "$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" ]
}

The schema is shipped with the package and can be accessed like so:

schema <- system.file("example_schema_catalog.json", package = "rjsonschema")

We can now validate a JSON object against the schema:

validate(
  schema,
  '{"productId": 1, "productName": "A green door", "price": 12.50}'
)
#> [1] TRUE

Note that instance can also be an R list directly (will be converted to JSON for validation):

validate(
  schema,
  list(productId = 1, productName = "A green door", price = 12.50)
)
#> [1] TRUE

The JSON object is valid, as it adheres to the schema.

However, the following JSON object is not valid:

validate(
  schema,
  '{"productId": "1", "productName": "A green door", "price": 0}'
)
#> [1] FALSE
res <- validate(
  schema,
  '{"productId": "1", "productName": "A green door", "price": 0}',
  style = "basic"
)
str(res)
#> List of 1
#>  $ :List of 2
#>   ..$ errors:List of 2
#>   .. ..$ :List of 4
#>   .. .. ..$ absoluteKeywordLocation: chr "https://example.com/product.schema.json#/properties/price/exclusiveMinimum"
#>   .. .. ..$ error                  : chr "0 is less than or equal to the minimum of 0"
#>   .. .. ..$ instanceLocation       : chr "/price"
#>   .. .. ..$ keywordLocation        : chr "/properties/price/exclusiveMinimum"
#>   .. ..$ :List of 4
#>   .. .. ..$ absoluteKeywordLocation: chr "https://example.com/product.schema.json#/properties/productId/type"
#>   .. .. ..$ error                  : chr "\"1\" is not of type \"integer\""
#>   .. .. ..$ instanceLocation       : chr "/productId"
#>   .. .. ..$ keywordLocation        : chr "/properties/productId/type"
#>   ..$ valid : logi FALSE