JSONSchex (jsonschex v0.2.1)

Copy Markdown View Source

JSON Schema Draft 2020-12 validator for Elixir.

Compile a schema once, then validate data against it repeatedly:

iex> schema = %{"type" => "integer", "minimum" => 10}
iex> {:ok, compiled} = JSONSchex.compile(schema)
iex> JSONSchex.validate(compiled, 15)
:ok
iex> {:error, [error]} = JSONSchex.validate(compiled, 5)
iex> error.rule
:minimum
iex> JSONSchex.format_error(error)
"Value 5 is less than minimum 10"

With format assertion:

iex> schema = %{"type" => "string", "format" => "email"}
iex> {:ok, compiled} = JSONSchex.compile(schema, format_assertion: true)
iex> JSONSchex.validate(compiled, "user@example.com")
:ok
iex> {:error, [error]} = JSONSchex.validate(compiled, "not-an-email")
iex> error.rule
:format
iex> JSONSchex.format_error(error)
"Format mismatch: email"

Summary

Functions

Compiles a raw JSON Schema into a reusable Schema struct.

Formats a validation error into a human-readable string.

Validates data against a compiled schema.

Functions

compile(schema, opts \\ [])

Compiles a raw JSON Schema into a reusable Schema struct.

Options

  • :external_loader(uri -> {:ok, map()} | {:error, term()}) for remote $ref schemas

  • :base_uri — Starting base URI for resolving relative references
  • :format_assertion — Enable strict format validation (default: false)
  • :content_assertion — Enable strict content vocabulary validation (default: false)

See the Loader guide and Content and Format guide for details.

Examples

iex> {:ok, schema} = JSONSchex.compile(%{"type" => "string"})
iex> is_struct(schema, JSONSchex.Types.Schema)
true

iex> {:ok, schema} = JSONSchex.compile(%{"type" => "string", "format" => "email"}, format_assertion: true)
iex> JSONSchex.validate(schema, "test@example.com")
:ok

format_error(error)

Formats a validation error into a human-readable string.

Examples

iex> error = %JSONSchex.Types.Error{path: ["age", "user"], rule: :minimum, context: %{minimum: 0, actual: -5}}
iex> JSONSchex.format_error(error)
"At /user/age: Value -5 is less than minimum 0"

iex> {:error, error} = JSONSchex.compile(%{"type" => "1"})
iex> JSONSchex.format_error(error)
~s(Keyword 'type' must be one of [string, integer, number, boolean, object, array, null], got: "1")

iex> {:error, error} = JSONSchex.compile(%{"minimum" => "five"})
iex> JSONSchex.format_error(error)
~s(Keyword 'minimum' must be a number, got: "five")

iex> {:error, error} = JSONSchex.compile(%{"multipleOf" => -3})
iex> JSONSchex.format_error(error)
~s(Keyword 'multipleOf' must be a strictly positive number, got: -3)

iex> {:error, error} = JSONSchex.compile(%{"minLength" => -1})
iex> JSONSchex.format_error(error)
~s(Keyword 'minLength' must be a non-negative integer, got: -1)

iex> {:error, error} = JSONSchex.compile(%{"uniqueItems" => "yes"})
iex> JSONSchex.format_error(error)
~s(Keyword 'uniqueItems' must be a boolean, got: "yes")

validate(schema, data)

@spec validate(JSONSchex.Types.Schema.t(), term()) ::
  :ok | {:error, [JSONSchex.Types.Error.t()]}

Validates data against a compiled schema.

Returns :ok or {:error, [Error.t()]}. Use JSONSchex.format_error/1 on individual errors to produce human-readable messages.

Examples

iex> {:ok, schema} = JSONSchex.compile(%{"type" => "integer"})
iex> JSONSchex.validate(schema, 42)
:ok

iex> {:ok, schema} = JSONSchex.compile(%{"type" => "integer"})
iex> {:error, errors} = JSONSchex.validate(schema, "not an integer")
iex> [error] = errors
iex> error.rule
:type
iex> error.path
[]
iex> JSONSchex.format_error(error)
"Expected type \"integer\", got \"string\""