JSV.Schema (jsv v0.5.1)
View SourceThis module defines a struct where all the supported keywords of the JSON schema specification are defined as keys. Text editors that can predict the struct keys will make autocompletion available when writing schemas.
Using in build
The JSV.Schema
struct can be given to JSV.build/2
:
schema = %JSV.Schema{type: :integer}
JSV.build(schema, options())
Because Elixir structs always contain all their defined keys, writing a schema
as %JSV.Schema{type: :integer}
is actually defining the following:
%JSV.Schema{
type: :integer,
"$id": nil
additionalItems: nil,
additionalProperties: nil,
allOf: nil,
anyOf: nil,
contains: nil,
# etc...
}
For that reason, when giving a JSV.Schema
struct to
JSV.build/2
, any nil
value is ignored. This is not the case with other
strucs or maps.
Note that JSV.build/2
does not require JSV.Schema
structs, any
map with binary or atom keys is accepted.
This is also why the JSV.Schema
struct does not define the
const
keyword, because nil
is a valid value for that keyword but there is
no way to know if the value was omitted or explicitly defined as nil
. To
circumvent that you may use the enum
keyword or just use a regular map
instead of this module's struct:
%JSV.Schema{enum: [nil]}
# OR
%{const: nil}
Functional helpers
This module also exports a small range of utility functions to ease writing schemas in a functional way.
This is mostly useful when generating schemas dynamically, or for shorthands.
For instance, instead of writing the following:
%Schema{
type: :object,
properties: %{
name: %Schema{type: :string, description: "the name of the user"},
age: %Schema{type: :integer, description: "the age of the user"}
},
required: [:name, :age]
}
One can write:
%Schema{}
|> Schema.props(
name: Schema.string(description: "the name of the user"),
age: Schema.integer(description: "the age of the user")
)
|> Schema.required([:name, :age])
Summary
Functions
Returns a schema with type: :boolean
.
Returns a schema with type: :integer
.
Returns a schema with type: :array
and items: item_schema
.
Returns a new JSV.Schema
struct with the given key/values.
Returns the given term with all atoms converted to binaries except for special cases.
Returns a schema with type: :number
.
Returns a schema with type: :object
.
Updates the given JSV.Schema
struct with the given key/values.
Returns a schema with the type: :object
and the given properties
.
Returns a schema with "$ref": ref
.
Adds the given key or keys in the base schema :required
property. Previous
values are preserved.
Returns a schema with type: :string
.
Returns the given schema as a map without keys containing a nil
value.
Types
@type base() :: prototype() | nil
@type schema_data() :: %{optional(binary()) => schema_data()} | [schema_data()] | number() | binary() | boolean() | nil
@type t() :: %JSV.Schema{ "$anchor": term(), "$comment": term(), "$defs": term(), "$dynamicAnchor": term(), "$dynamicRef": term(), "$id": term(), "$ref": term(), "$schema": term(), additionalItems: term(), additionalProperties: term(), allOf: term(), anyOf: term(), contains: term(), contentEncoding: term(), contentMediaType: term(), contentSchema: term(), default: term(), dependencies: term(), dependentRequired: term(), dependentSchemas: term(), deprecated: term(), description: term(), else: term(), enum: term(), examples: term(), exclusiveMaximum: term(), exclusiveMinimum: term(), format: term(), if: term(), items: term(), "jsv-struct": term(), maxContains: term(), maxItems: term(), maxLength: term(), maxProperties: term(), maximum: term(), minContains: term(), minItems: term(), minLength: term(), minProperties: term(), minimum: term(), multipleOf: term(), not: term(), oneOf: term(), pattern: term(), patternProperties: term(), prefixItems: term(), properties: term(), propertyNames: term(), readOnly: term(), required: term(), then: term(), title: term(), type: term(), unevaluatedItems: term(), unevaluatedProperties: term(), uniqueItems: term(), writeOnly: term() }
Functions
Returns a schema with type: :boolean
.
Returns a schema with type: :integer
.
Returns a schema with type: :array
and items: item_schema
.
Returns a new JSV.Schema
struct with the given key/values.
@spec normalize(term()) :: %{optional(binary()) => schema_data()} | [schema_data()] | number() | binary() | boolean() | nil
Returns the given term with all atoms converted to binaries except for special cases.
Note that this function accepts any data and not actually a %JSV.Schema{}
or
a raw schema.
JSV.Schema
structs pairs where the value isnil
will be completely removed.%JSV.Schema{type: :object}
becomes%{"type" => "object"}
whereas the struct contains many more keys.- Structs will be simply converted to map with
Map.from_struct/1
, not JSON encoder protocol will be used. true
,false
andnil
will be kept as-is in all places except map keys.true
,false
andnil
as map keys will be converted to string.- Other atoms will be checked to see if they correspond to a module name that
exports a
schema/0
function.
In any case, the resulting function will alway contain no atom other than
true
, false
or nil
.
Examples
iex> JSV.Schema.normalize(%JSV.Schema{title: :"My Schema"})
%{"title" => "My Schema"}
iex> JSV.Schema.normalize(%{name: :joe})
%{"name" => "joe"}
iex> JSV.Schema.normalize(%{"name" => :joe})
%{"name" => "joe"}
iex> JSV.Schema.normalize(%{"name" => "joe"})
%{"name" => "joe"}
iex> JSV.Schema.normalize(%{true: false})
%{"true" => false}
iex> JSV.Schema.normalize(%{specials: [true, false, nil]})
%{"specials" => [true, false, nil]}
iex> map_size(JSV.Schema.normalize(%JSV.Schema{}))
0
iex> JSV.Schema.normalize(1..10)
%{"first" => 1, "last" => 10, "step" => 1}
iex> defmodule :some_module_with_schema do
iex> def schema, do: %{}
iex> end
iex> JSV.Schema.normalize(:some_module_with_schema)
%{"$ref" => "jsv:module:some_module_with_schema"}
iex> defmodule :some_module_without_schema do
iex> def hello, do: "world"
iex> end
iex> JSV.Schema.normalize(:some_module_without_schema)
"some_module_without_schema"
Returns a schema with type: :number
.
Returns a schema with type: :object
.
See props/2
to define the properties as well.
Updates the given JSV.Schema
struct with the given key/values.
Accepts nil
as the base schema, which is equivalent to new(overrides)
.
Returns a schema with the type: :object
and the given properties
.
Returns a schema with "$ref": ref
.
Adds the given key or keys in the base schema :required
property. Previous
values are preserved.
Returns a schema with type: :string
.
Returns the given schema as a map without keys containing a nil
value.