Skema.JsonSchema (Skema v1.5.0)

Copy Markdown View Source

Utilities for converting between Skema schema maps and JSON Schema format.

This module provides bidirectional conversion between Skema schema definitions and JSON Schema documents, enabling interoperability with JSON Schema-based systems and tools.

Features

  • Convert Skema schema maps to JSON Schema format
  • Convert JSON Schema documents to Skema schema maps
  • Support for common types, validations, and constraints
  • Configurable schema metadata (title, description, version)

Limitations

  • Only supports schema maps, not schema modules (defschema)
  • Arrays must always specify item type as {:array, item_type} - generic :array type is not supported
  • Some advanced features may not have direct equivalents
  • Custom functions and transformations are not supported

Security

By default, JSON Schema field names are converted to strings to prevent atom exhaustion attacks. Use the :atom_keys option only with trusted input where field names are known and limited.

Examples

# Skema to JSON Schema
schema = %{
  name: [type: :string, required: true, length: [min: 2, max: 50], doc: "User's full name"],
  age: [type: :integer, number: [min: 0, max: 150], doc: "Age in years"],
  tags: [type: {:array, :string}]
}

json_schema = Skema.JsonSchema.from_schema(schema)

# JSON Schema to Skema
json_schema = %{
  "type" => "object",
  "properties" => %{
    "name" => %{"type" => "string", "minLength" => 2, "maxLength" => 50, "description" => "User's full name"},
    "age" => %{"type" => "integer", "minimum" => 0, "maximum" => 150, "description" => "Age in years"},
    "tags" => %{"type" => "array", "items" => %{"type" => "string"}}
  },
  "required" => ["name"]
}

skema_schema = Skema.JsonSchema.to_schema(json_schema)

Summary

Functions

Converts a Skema schema map to JSON Schema format.

Converts a JSON Schema document to a Skema schema map.

Types

schema_opts()

@type schema_opts() :: [
  schema_version: String.t(),
  title: String.t(),
  description: String.t(),
  default_type: atom(),
  strict: boolean(),
  atom_keys: boolean(),
  per_field_required: boolean()
]

Functions

from_schema(schema, opts \\ [])

@spec from_schema(map(), schema_opts()) :: map()

Converts a Skema schema map to JSON Schema format.

Options

  • :schema_version - JSON Schema version URI (default: "https://json-schema.org/draft/2020-12/schema")
  • :title - Schema title
  • :description - Schema description
  • :per_field_required - When true, output required as per-field property instead of array (default: false)

Examples

schema = %{
  name: [type: :string, required: true],
  age: [type: :integer, number: [min: 0]]
}

json_schema = Skema.JsonSchema.from_schema(schema, title: "User Schema")

to_schema(json_schema, opts \\ [])

@spec to_schema(map(), schema_opts()) :: map()

Converts a JSON Schema document to a Skema schema map.

Options

  • :strict - When false, skip unsupported features instead of raising (default: false)
  • :default_type - Default type when type is not specified (default: :any)
  • :atom_keys - Convert field names to atoms (default: false, uses strings for security)
  • :per_field_required - When true, check for per-field required property instead of required array (default: false)

Examples

json_schema = %{
  "type" => "object",
  "properties" => %{
    "name" => %{"type" => "string"},
    "age" => %{"type" => "integer", "minimum" => 0}
  },
  "required" => ["name"]
}

skema_schema = Skema.JsonSchema.to_schema(json_schema)

Security Note

By default, field names are converted to strings to prevent atom exhaustion attacks. Only use atom_keys: true with trusted input where field names are known and limited.