Giter Club home page Giter Club logo

ex_json_schema's Introduction

Elixir JSON Schema validator

Build Status Coverage Status Hex.pm Hex.pm

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.6.1"}]
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).

License

Released under the MIT license.

TODO

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

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.