jddf v0.1.1 JDDF.Validator View Source

Validates JSON data against instances of JDDF.Schema.

Validators have two properties to control how validation behaves:

  • max_depth controls how "deeply" references in JDDF schemas (using the ref JDDF keyword) should be followed. If max_depth is exceeded, then validate/3 or validate!/3 will throw JDDF.Validator.MaxDepthExceededError.

    For example, setting max_depth to 5 means that a 5-deep chain of refs would trigger JDDF.Validator.MaxDepthExceededError.

    By default, max_depth is 0. A max_depth of 0 disables any maximum depth; JDDF.Validator.MaxDepthExceededError will never be thrown. In this case, validating against a circularly-defined schema may exhaust all memory.

  • max_errors controls the maximum number of errors to return. If max_errors is set to N, then validate/3 and validate!/3 will return NJDDF.Validator.ValidationErrors or fewer. You can use max_errors to optimize JDDF validation.

    For example, if you only care about whether there exist any validation errors for an input, you can set max_errors to 1.

    By default, max_errors is 0. A max_errors of 0 disables any maximum number of errors; validate/3 and validate!/3 will return all errors.

The examples below demonstrate max_depth and max_errors. See also the docs for JDDF for more introductory examples.

Examples

Here's an example of max_depth causing an error, rather than letting a circularly-defined schema cause an infinite loop:

iex> schema = JDDF.Schema.from_json!(%{
...>   "definitions" => %{
...>     "loop" => %{ "ref" => "loop" },
...>   },
...>   "ref" => "loop",
...> })
iex> validator = %JDDF.Validator{max_depth: 32}
%JDDF.Validator{max_depth: 32, max_errors: 0}
iex> JDDF.Validator.validate!(validator, schema, nil)
** (JDDF.Validator.MaxDepthExceededError) maximum depth exceeded during validation

Here's an example of max_errors limiting the return value to just 1 value:

iex> schema = JDDF.Schema.from_json!(%{
...>   "elements" => %{ "type" => "string" }
...> })
iex> validator = %JDDF.Validator{max_errors: 1}
%JDDF.Validator{max_depth: 0, max_errors: 1}
iex> length(JDDF.Validator.validate!(validator, schema, [nil, nil, nil, nil, nil]))
1

Instead of returning five errors (one for each element of [nil, nil, nil, nil, nil]), just one error comes back. Internally, validate/3 and validate!/3 optimizes for max_errors, and stops validation as soon as max_errors is reached.

Link to this section Summary

Functions

Validate a JDDF.Schema against a JSON input (an "instance").

Validate a JDDF.Schema against a JSON input (an "instance").

Link to this section Types

Link to this type

t()

View Source
t() :: %JDDF.Validator{max_depth: integer(), max_errors: integer()}

Link to this section Functions

Link to this function

validate(validator, schema, instance)

View Source
validate(
  validator :: JDDF.Validator.t(),
  schema :: JDDF.Schema.t(),
  instance :: any()
) ::
  {:ok, [JDDF.Validator.ValidationError.t()]}
  | {:error, JDDF.Validator.MaxDepthExceededError.t()}

Validate a JDDF.Schema against a JSON input (an "instance").

instance should be an Elixir representation of JSON data. You should first parse the JSON before passing it into validate/3. You can construct this data manually, or parse it using:

Most JSON implementations for Elixir are compatible with this function.

See JDDF.Validator docs for how to control certain aspects of this function. This function implements the formal specification of JSON Data Definition Format validation.

iex> JDDF.Validator.validate(
...>   %JDDF.Validator{},
...>   JDDF.Schema.from_json!(%{"type" => "boolean"}),
...>   nil
...> )
{:ok, [%JDDF.Validator.ValidationError{instance_path: [], schema_path: ["type"]}]}

iex> schema = JDDF.Schema.from_json!(%{
...>   "definitions" => %{
...>     "loop" => %{ "ref" => "loop" },
...>   },
...>   "ref" => "loop",
...> })
iex> validator = %JDDF.Validator{max_depth: 32}
%JDDF.Validator{max_depth: 32, max_errors: 0}
iex> JDDF.Validator.validate(validator, schema, nil)
{:error, %JDDF.Validator.MaxDepthExceededError{message: "maximum depth exceeded during validation"}}
Link to this function

validate!(validator, schema, instance)

View Source
validate!(
  validator :: JDDF.Validator.t(),
  schema :: JDDF.Schema.t(),
  instance :: any()
) :: [JDDF.Validator.ValidationError.t()]

Validate a JDDF.Schema against a JSON input (an "instance").

Similar to validate/3, except it will unwrap the result and will raise in case of errors.

iex> JDDF.Validator.validate!(
...>   %JDDF.Validator{},
...>   JDDF.Schema.from_json!(%{"type" => "boolean"}),
...>   nil
...> )
[%JDDF.Validator.ValidationError{instance_path: [], schema_path: ["type"]}]

iex> schema = JDDF.Schema.from_json!(%{
...>   "definitions" => %{
...>     "loop" => %{ "ref" => "loop" },
...>   },
...>   "ref" => "loop",
...> })
iex> validator = %JDDF.Validator{max_depth: 32}
%JDDF.Validator{max_depth: 32, max_errors: 0}
iex> JDDF.Validator.validate!(validator, schema, nil)
** (JDDF.Validator.MaxDepthExceededError) maximum depth exceeded during validation