Zoi.JSONSchema (Zoi v0.19.0)

Copy Markdown View Source

JSON Schema is a declarative language for annotating and validating JSON document's structure, constraints, and data types. It helps you standardize and define expectations for JSON data.

Zoi provides functionality to convert its type definitions into JSON Schema format, enabling seamless integration with systems that utilize JSON Schema for data validation and documentation. It also supports decoding existing JSON Schemas back into Zoi schemas via Zoi.from_json_schema/1.

Examples

Encoding a Zoi schema:

iex> schema = Zoi.map(%{name: Zoi.string(), age: Zoi.integer()})
iex> Zoi.to_json_schema(schema)
%{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  type: :object,
  properties: %{
    name: %{type: :string},
    age: %{type: :integer}
  },
  required: [:name, :age],
  additionalProperties: false
}

Decoding a JSON Schema:

iex> json = %{"type" => "object", "properties" => %{"name" => %{"type" => "string"}}, "required" => ["name"]}
iex> schema = Zoi.from_json_schema(json)
iex> Zoi.parse(schema, %{"name" => "Alice"})
{:ok, %{"name" => "Alice"}}

Type mapping

ZoiJSON Schema
Zoi.string/1"string"
Zoi.integer/1"integer"
Zoi.float/1"number"
Zoi.number/1"number"
Zoi.decimal/1"number"
Zoi.boolean/1"boolean"
Zoi.null/1"null"
Zoi.any/1unconstrained schema ({})
Zoi.none/1false
Zoi.literal/2const
Zoi.enum/2enum
Zoi.array/2"array"
Zoi.map_set/2"array" with uniqueItems
Zoi.tuple/2"array" with prefixItems
Zoi.map/2"object"
Zoi.struct/3"object" (the Elixir module is not encoded)
Zoi.union/2anyOf
Zoi.exclusive_union/2oneOf
Zoi.intersection/2allOf
Zoi.nullable/2nullable type via anyOf
Zoi.date/1 and Zoi.ISO.date/1"string" with format: "date"
Zoi.datetime/1 and Zoi.ISO.datetime/1"string" with format: "date-time"
Zoi.naive_datetime/1 and Zoi.ISO.naive_datetime/1"string" with format: "date-time"
Zoi.time/1 and Zoi.ISO.time/1"string" with format: "time"
Zoi.email/1"string" with format: "email"
Zoi.url/1"string" with format: "uri"
Zoi.uuid/1"string" with format: "uuid"

Metadata

Zoi.to_json_schema/1 incorporates description, example, and deprecated options into the resulting JSON Schema:

iex> schema = Zoi.string(description: "A simple string", example: "Hello, World!")
iex> Zoi.to_json_schema(schema)
%{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  type: :string,
  description: "A simple string",
  example: "Hello, World!"
}

When a schema is marked as deprecated, the generated JSON Schema will include deprecated: true (the deprecation message itself is not part of JSON Schema):

iex> schema = Zoi.string(deprecated: "Use another field")
iex> Zoi.to_json_schema(schema)
%{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  type: :string,
  deprecated: true
}

Additional JSON Schema annotations can be set via the :metadata option. The recognised keys are :title, :examples, :read_only, :write_only, :id, :comment, :content_encoding and :content_media_type. They are emitted as the matching JSON Schema keywords ($id and $comment for :id and :comment):

iex> schema = Zoi.string(metadata: [title: "Username", examples: ["alice", "bob"], read_only: true])
iex> Zoi.to_json_schema(schema)
%{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  type: :string,
  title: "Username",
  examples: ["alice", "bob"],
  readOnly: true
}

Limitations

  • Complex types or custom types not listed above will raise an error during conversion.
  • Some advanced Zoi features may not have direct equivalents in JSON Schema.
  • Refinements are partially supported, primarily for string patterns and length constraints.
  • Additional properties in objects are disallowed by default (additionalProperties: false).

References

Summary

Functions

Decodes a JSON Schema map or boolean into a Zoi schema.

Encodes a Zoi schema into a JSON Schema map or boolean.

Functions

decode(json_schema)

@spec decode(map() | boolean()) :: Zoi.schema()

Decodes a JSON Schema map or boolean into a Zoi schema.

Maps must have string keys, as produced by a JSON parser. true accepts any value; false rejects every value.

Examples

iex> json = %{"type" => "object", "properties" => %{"name" => %{"type" => "string"}}, "required" => ["name"]}
iex> schema = Zoi.JSONSchema.decode(json)
iex> Zoi.parse(schema, %{"name" => "Alice"})
{:ok, %{"name" => "Alice"}}

encode(schema)

@spec encode(Zoi.schema()) :: map() | boolean()

Encodes a Zoi schema into a JSON Schema map or boolean.

Examples

iex> schema = Zoi.map(%{name: Zoi.string()})
iex> Zoi.JSONSchema.encode(schema)
%{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  type: :object,
  properties: %{name: %{type: :string}},
  required: [:name],
  additionalProperties: false
}