Git Product home page Git Product logo

ex_json_schema's Introduction

Elixir JSON Schema Validator

Build Status Coverage Status Module Version Hex Docs Total Download License Last Updated

A JSON Schema validator with full support for the draft 4 specification and zero dependencies. Passes the official JSON Schema Test Suite.

Installation

Add the project to your Mix dependencies in mix.exs:

defp deps do
  [
    {:ex_json_schema, "~> 0.7.4"}
  ]
end

Update your dependencies with:

$ mix deps.get

Loading remote schemata

If you have remote schemata that need to be fetched at runtime, you have to register a function that takes a URL and returns a Map of the parsed JSON. So in your Mix configuration in config/config.exs you should have something like this:

config :ex_json_schema,
  :remote_schema_resolver,
  fn url -> HTTPoison.get!(url).body |> Poison.decode! end

Alternatively, you can specify a module and function name for situations where using anonymous functions is not possible (i.e. working with Erlang releases):

config :ex_json_schema,
  :remote_schema_resolver,
  {MyModule, :my_resolver}

You do not have to do that for the official draft 4 meta-schema found at http://json-schema.org/draft-04/schema# though. That schema is bundled with the project and will work out of the box without any network calls.

Resolving a schema

In this step the schema is validated against its meta-schema (the draft 4 schema definition) and $refs are being resolved (making sure that the reference points to an existing fragment). You should only resolve a schema once to avoid the overhead of resolving it in every validation call.

schema = %{
  "type" => "object",
  "properties" => %{
    "foo" => %{
      "type" => "string"
    }
  }
} |> ExJsonSchema.Schema.resolve()

Note that Map keys are expected to be strings, since in practice that data will always come from some JSON parser.

Usage

If you're only interested in whether a piece of data is valid according to the schema:

iex> ExJsonSchema.Validator.valid?(schema, %{"foo" => "bar"})
true

iex> ExJsonSchema.Validator.valid?(schema, %{"foo" => 1})
false

Or in case you want to have detailed validation errors:

iex> ExJsonSchema.Validator.validate(schema, %{"foo" => "bar"})
:ok

iex> ExJsonSchema.Validator.validate(schema, %{"foo" => 1})
{:error, [{"Type mismatch. Expected String but got Integer.", "#/foo"}]}

Validation error formats

By default, errors are formatted using a string formatter that returns errors as tuples of error message and path. If you want to get raw validation error structs, you can pass the following option:

iex> ExJsonSchema.Validator.validate(schema, %{"foo" => 1}, error_formatter: false)
{:error,
 [
   %ExJsonSchema.Validator.Error{
     error: %ExJsonSchema.Validator.Error.Type{
       actual: "integer",
       expected: ["string"]
     },
     path: "#/foo"
   }
 ]}

Custom error formatter

You can also pass your own custom error formatter as a module that implements a format/1 function that takes a list of raw errors via the same option:

defmodule MyFormatter do
  def format(errors) do
    Enum.map(errors, fn %ExJsonSchema.Validator.Error{error: error, path: path} ->
      {error.__struct__, path}
    end)
  end
end
iex> ExJsonSchema.Validator.validate(schema, %{"foo" => 1}, error_formatter: MyFormatter)
{:error, [{ExJsonSchema.Validator.Error.Type, "#/foo"}]}

Validating against a fragment

It is also possible to validate against a subset of the schema by providing either a fragment:

iex> fragment = ExJsonSchema.Schema.get_fragment!(schema, "#/properties/foo")
%{"type" => "string"}

iex> ExJsonSchema.Validator.valid_fragment?(schema, fragment, "bar")
true

iex> ExJsonSchema.Validator.validate_fragment(schema, fragment, "bar")
:ok

or a path:

iex> ExJsonSchema.Validator.valid_fragment?(schema, "#/foo", "bar")
true

Format support

The validator supports all the formats specified by draft 4 (date-time, email, hostname, ipv4, ipv6), with the exception of the uri format which has confusing/broken requirements in the official test suite (see json-schema-org/JSON-Schema-Test-Suite#77).

Custom formats

The JSON schema spec states that the format property "allows values to be constrained beyond what the other tools in JSON Schema can do". To support this, you can configure a callback validator function which gets called when a format property is encountered that is not one of the builtin formats.

As a global configuration option:

config :ex_json_schema,
  :custom_format_validator,
  {MyModule, :validate}

Or by passing an option when resolving the schema:

ExJsonSchema.Schema.resolve(%{"format" => "custom"}, custom_format_validator: {MyModule, :validate})

The configured function is called with the arguments (format, data) and is expected to return either true or false, depending whether the data is valid for the given format. For compatibility with JSON schema, it is expected to return true when the format is unknown by your callback function.

License

Copyright (c) 2015 Jonas Schmidt

Released under the MIT license.

TODO

  • Add some source code documentation
  • Enable providing JSON for known schemata at resolve time

ex_json_schema's People

Contributors

jonasschmidt avatar ananthakumaran avatar bmanuel avatar the-guitarman avatar sean-lin avatar alanvenegas avatar hzamani avatar jbottigliero avatar kianmeng avatar mogorman avatar thomasarts avatar odk211 avatar woylie avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.