Exonerate supports JSONSchema format validation through the :format option.
This guide details all available format filters and how to configure them.
Basic Usage
To enable format validation, pass the :format option to any Exonerate macro:
Exonerate.function_from_string(:def, :validate, """
{"type": "string", "format": "email"}
""", format: true)Configuration
The :format option accepts either true or a keyword list:
true: shorthand for[default: true]keywords:
:at: a list of{<json pointer>, <filter-spec>}tuples to apply format filters in specific locations in the schema. This can be used to specify custom filters for non-default format types. It can also be used to override default formatting.<json pointer>should be a string which may be relative if no"id"or"$id"metadata are present in the parents of the location. Otherwise, the pointer must the a uri of the nearest parent containing"id"or"$id"metadata, with the relative pointer applied as the fragment of the uri.<filter-spec>may either be a module, which implies the existence of themodule.validate/1function,{module, function}which implies the existence ofmodule.function/1, or{module, function, [extra-args]}which implies the existence ofmodule.function/nwhere the extra args are appended to the end of string to be validated.In all cases, the validation function is expected to emit
:okif the string validates, or{:error, reason}, if it does not.reasonshould either be a string ornil.:type: a list of{<format-type>, <filter-spec>}to apply across the schema whenever<format-type>is encountered. This can be used to specify custom filters for non-default format types. It can also be used to override default formatting.<filter-spec>is as above.:default:trueto enable all default filters or a list of strings specifying the default format types to enable.
Available Format Types
Date and Time
"date-time"
Enables the default date-time filter for all {"format": "date-time"} contexts.
This uses Elixir's NaiveDateTime.from_iso8601/1 parser.
"date-time-utc"
Enables the default date-time-utc filter for all {"format": "date-time-utc"} contexts.
This uses Elixir's DateTime.from_iso8601/1 parser, and requires the offset to be
0 from UTC.
"date-time-tz"
Enables the default date-time filter for all {"format": "date-time-tz"} context strings.
This uses Elixir's DateTime.from_iso8601/1 parser, which requires an offset to
be specified.
"date"
Enables the default date filter for all {"format": "date"} context strings.
This uses Elixir's Date.from_iso8601/1 parser.
"time"
Enables the default time filter for all {"format": "time"} context strings.
This uses Elixir's Time.from_iso8601/1 parser.
"duration"
Enables the default duration filter for all {"format": "duration"} context strings.
This uses a custom ABNF validator that matches Appendix A of RFC 3339:
https://www.rfc-editor.org/rfc/rfc3339.txt
The validation function can be generated by Exonerate.Formats.Duration.
Requires NimbleParsec and Pegasus dependencies.
Network
"ipv4"
Enables the default ipv4 filter for all {"format": "ipv4"} context strings.
This uses Erlang's :inet.parse_ipv4strict_address/1 parser.
"ipv6"
Enables the default ipv6 filter for all {"format": "ipv6"} context strings.
This uses Erlang's :inet.parse_ipv6strict_address/1 parser.
"email"
Enables the default email filter for all {"format": "email"} context strings.
This uses a custom ABNF validator that matches section 4.1.2 of RFC 5322:
https://www.rfc-editor.org/rfc/rfc5322.txt
The validation function can be generated by Exonerate.Formats.Email.
Requires NimbleParsec and Pegasus dependencies.
"idn-email"
Enables the default idn-email (i18n email address) filter for all
{"format": "idn-email"} context strings. This uses a custom ABNF validator
that matches section 3.3 of RFC 6531: https://www.rfc-editor.org/rfc/rfc5322.txt
The validation function can be generated by Exonerate.Formats.IdnEmail.
Requires NimbleParsec and Pegasus dependencies.
"hostname"
Enables the default hostname filter for all {"format": "hostname"} context strings.
This uses a custom ABNF validator that matches section 2.1 of RFC 1123:
https://www.rfc-editor.org/rfc/rfc1123.txt
The validation function can be generated by Exonerate.Formats.Hostname.
Requires NimbleParsec and Pegasus dependencies.
"idn-hostname"
Enables the default idn-hostname (i18n hostname) filter for all
{"format": "idn-hostname"} context strings.
Note that in order to use this filter, you must add the :idna library to your dependencies.
The validation function can be generated by Exonerate.Formats.IdnHostname.
Requires NimbleParsec and Pegasus dependencies.
URIs and IRIs
"uri"
Enables the default uri filter for all {"format": "uri"} context strings.
This uses a custom ABNF validator that matches section 3 of RFC 3986:
https://www.rfc-editor.org/rfc/rfc3986.txt.
Absolute URIs
URIs must be absolute, i.e. they must contain a scheme, host,
and path. If you need relative URIs, use the uri-reference filter.
The validation function can be generated by Exonerate.Formats.Uri.
Requires NimbleParsec and Pegasus dependencies.
"uri-reference"
Enables the default uri-reference filter for all {"format": "uri-reference"} context strings.
This uses a custom ABNF validator that matches section 3 of RFC 3986:
https://www.rfc-editor.org/rfc/rfc3986.txt.
The validation function can be generated by Exonerate.Formats.UriReference.
Requires NimbleParsec and Pegasus dependencies.
"iri"
Enables the default iri (i18n uri) filter for all {"format": "iri"} context strings.
This uses a custom ABNF validator that matches section 2.2 of RFC 3987:
https://www.rfc-editor.org/rfc/rfc3987.txt.
Absolute IRIs
IRIs must be absolute, i.e. they must contain a scheme, host,
and path. If you need relative IRIs, use the iri-reference filter.
The validation function can be generated by Exonerate.Formats.Iri.
Requires NimbleParsec and Pegasus dependencies.
"iri-reference"
Enables the default iri-reference (i18n uri) for all {"format": "iri-reference"} context strings.
This uses a custom ABNF validator that matches section 2.2 of RFC 3987:
https://www.rfc-editor.org/rfc/rfc3987.txt.
The validation function can be generated by Exonerate.Formats.IriReference.
Requires NimbleParsec and Pegasus dependencies.
"uri-template"
Enables the default uri-template filter for all {"format": "uri-template"} context strings.
This uses a custom ABNF validator that matches section 2.3 of RFC 6570:
https://www.rfc-editor.org/rfc/rfc6570.txt.
URI-Template parent
uri-templates are templated against iri-reference strings. This means they do not need to be absolute, and they may include unicode characters.
The validation function can be generated by Exonerate.Formats.UriTemplate.
Requires NimbleParsec and Pegasus dependencies.
JSON Pointers
"json-pointer"
Enables the default json-pointer filter for all {"format": "json-pointer"} context strings.
This uses a custom ABNF validator that matches section 3 of RFC 6901:
https://www.rfc-editor.org/rfc/rfc6901.txt
The validation function can be generated by Exonerate.Formats.JsonPointer.
Requires NimbleParsec and Pegasus dependencies.
"relative-json-pointer"
Enables the default relative-json-pointer filter for all
{"format": "relative-json-pointer"} context strings.
This uses a custom ABNF validator that matches the following RFC proposal:
https://datatracker.ietf.org/doc/html/draft-handrews-relative-json-pointer-01
The validation function can be generated by Exonerate.Formats.RelativeJsonPointer.
Requires NimbleParsec and Pegasus dependencies.
Other
"uuid"
Enables the default uuid filter for all {"format": "uuid"} context strings.
"regex"
Enables the default regex filter for all {"format": "regex"} context strings.
Note: this does not compile the regex, instead it uses a custom ABNF validator
that matches the ECMA-262 standard:
https://www.ecma-international.org/publications-and-standards/standards/ecma-262/
The validation function can be generated by Exonerate.Formats.Regex.
Requires NimbleParsec and Pegasus dependencies.
Custom Format Filters
You can define custom format filters by implementing a validation function that:
- Accepts a string as its first argument
- Returns
:okif the string validates - Returns
{:error, reason}if validation fails, wherereasonis a string ornil
Example
defmodule MyApp.Formats.PhoneNumber do
def validate(string) do
if Regex.match?(~r/^\+?[1-9]\d{1,14}$/, string) do
:ok
else
{:error, "invalid phone number format"}
end
end
end
# Use with :type option (applies globally)
Exonerate.function_from_string(:def, :validate, """
{"type": "string", "format": "phone"}
""", format: [type: [{"phone", MyApp.Formats.PhoneNumber}]])
# Use with :at option (applies at specific location)
Exonerate.function_from_string(:def, :validate, """
{"type": "object", "properties": {"phone": {"type": "string", "format": "phone"}}}
""", format: [at: [{"/properties/phone", MyApp.Formats.PhoneNumber}]])