Zoi.JSONSchema (Zoi v0.18.4)

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.literal/2const
Zoi.enum/2enum
Zoi.array/2"array"
Zoi.tuple/2"array" with prefixItems
Zoi.map/2"object"
Zoi.union/2oneOf (decode also accepts anyOf)
Zoi.intersection/2allOf
Zoi.nullable/2nullable type via oneOf
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 into a Zoi schema.

Encodes a Zoi schema into a JSON Schema map.

Functions

decode(json_schema)

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

Decodes a JSON Schema map into a Zoi schema.

The input must be a JSON-shaped map with string keys, as produced by a JSON parser.

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()

Encodes a Zoi schema into a JSON Schema map.

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
}