jddf v0.1.1 JDDF View Source

An Elixir implementation of JSON Data Definition Format, a schema language for JSON.

You can use this module to parse JDDF schemas, and then validate JSON data against those schemas.

JDDF doesn't parse JSON data. Instead, you should first parse JSON data, and then call JDDF with the parsed result. JDDF is compatible with the sort of data produced by Jason or Poison. You can also just pass in ordinary Elixir data structures, as the examples here will demonstrate.

Example

For example, let's parse the following JDDF schema:

{
  "properties": {
    "name": { "type": "string" },
    "age": { "type": "string" },
    "phones": {
      "elements": { "type": "string" }
    }
  }
}

And validate it against two inputs. The first passes all the validation rules:

{
  "name": "John Doe",
  "age": 42,
  "phones": [
    "+44 1234567",
    "+44 2345678",
  ]
}

But the second does not:

{
  "age": "42",
  "phones": [
    "+44 1234567",
    442345678,
  ]
}

With this second input, there are three problems:

  • name is missing
  • age has the wrong type
  • phones[1] has the wrong type

Let's see an example of how we would parse the schema, and then validate the two inputs against it. We'll expect to get back no errors for the first input, and we expect three validation errors for the second input:

To keep things simple, we'll use Elixir data structures directly in these examples. In real life, you'd probably parse this data using Jason.decode! or Poison.decode!.

iex> schema = JDDF.Schema.from_json!(%{
...>   "properties" => %{
...>     "name" => %{"type" => "string"},
...>     "age" => %{"type" => "uint32"},
...>     "phones" => %{
...>       "elements" => %{"type" => "string"},
...>     },
...>   },
...> })
iex> validator = %JDDF.Validator{}
%JDDF.Validator{max_depth: 0, max_errors: 0}
iex> JDDF.Validator.validate!(validator, schema, %{
...>   "name" => "John Doe",
...>   "age" => 42,
...>   "phones" => [
...>     "+44 1234567",
...>     "+44 2345678",
...>   ],
...> })
[]
iex> errors = Enum.sort(JDDF.Validator.validate!(validator, schema, %{
...>   "age" => "42",
...>   "phones" => [
...>     "+44 1234567",
...>     442345678,
...>   ],
...> }))
iex> length(errors)
3
iex> [e1, e2, e3] = errors
iex> e1
%JDDF.Validator.ValidationError{instance_path: [], schema_path: ["properties", "name"]}
iex> e2
%JDDF.Validator.ValidationError{instance_path: ["age"], schema_path: ["properties", "age", "type"]}
iex> e3
%JDDF.Validator.ValidationError{instance_path: ["phones", "1"], schema_path: ["properties", "phones", "elements", "type"]}