JSV.Resolver.Local (jsv v0.7.2)
View SourceThis module allows to build JSV.Resolver
implementations that resolves
schemas based on disk based on their $id
property. It is not itself a
JSV.Resolver
implementation.
To define your own local resolver, use
this module by providing the
:source
option with a path to a directory, a path to a file, or a list of
paths to directories and files:
schemas_dir = "priv/messaging/schemas"
other_schema = "priv/users/user-schema.schema.json"
defmodule MyApp.LocalResolver do
use JSV.Resolver.Local, source: [schemas_dir, other_schema]
end
The macro will read all .json
files from the given sources and build an
index mapping the $id
property of each schema to its JSON-deserialized
value.
For convenience, nested lists are accepted. Duplicated files accepted as well but not duplicates due to symlinks.
Compilation and caching
Schemas are loaded directly into the generated module code. The module will recompile everytime a loaded schema file is modified or deleted.
Recompilation will also happen when new files are added in directories listed as sources.
Debugging
The use JSV.Resolver.Local
also accepts the following options:
:warn
- Aboolean
flag enabling compilation warnings when a.json
file cannot be read or loaded properly. Defaults totrue
.:debug
- Aboolean
flag enabling printouts of the loaded schemas on compilation. Defaults tofalse
.
Example
The "priv/schemas/user-schema.schema.json"
file contains the following JSON
text:
{
"$id": "myapp:user-0.0.1",
"type": "object",
"properties": {
"username": {
"type": "string"
}
}
}
Then this can be used as a source in your module.
defmodule MyApp.LocalResolver do
use JSV.Resolver.Local, source: "priv/schemas"
end
You can now build validation roots (JSV.Root
) by referencing this user
schema in $ref
and by providing your resolver to the JSV.build!/2
function:
iex> schema = %{"$ref" => "myapp:user-0.0.1"}
iex> root = JSV.build!(schema, resolver: MyApp.LocalResolver)
iex> # Here we pass an invalid username (an integer)
iex> result = JSV.validate(%{"username" => 123}, root)
iex> match?({:error, %JSV.ValidationError{}}, result)
true
You can also directly fetch a schema from the defined module:
iex> MyApp.LocalResolver.resolve("myapp:user-0.0.1")
{:ok,
%{
"$id" => "myapp:user-0.0.1",
"type" => "object",
"properties" => %{"username" => %{"type" => "string"}}
}}
iex> MyApp.LocalResolver.resolve("myapp:other")
{:error, {:unknown_id, "myapp:other"}}
Remember that schemas are identified and resolved by their $id
property and
not their path.