Skema (Skema v1.0.1)
View SourceSkema is a simple schema validation and casting library for Elixir.
Provides four main APIs:
cast_and_validate/2
- casting and validating data with given schemacast/2
- casting data with given schemavalidate/2
- validating data with given schematransform/2
- transforming data with given schema
Define schema
Skema schema can be a map with field name as key and field definition as value, or a schema module.
schema = %{
email: [type: :string, required: true],
age: [type: :integer, number: [min: 18]],
hobbies: [type: {:array, :string}]
}
or using defschema:
defmodule UserSchema do
use Skema
defschema do
field :email, :string, required: true
field :age, :integer, number: [min: 18]
field :hobbies, {:array, :string}
end
end
Data Processing Pipeline
Skema provides a complete data processing pipeline:
- Cast - Convert raw input to proper types
- Validate - Check business rules and constraints
- Transform - Normalize, format, and compute derived values
# Full pipeline
raw_data = %{"email" => " JOHN@EXAMPLE.COM ", "age" => "25"}
with {:ok, cast_data} <- Skema.cast(raw_data, schema),
:ok <- Skema.validate(cast_data, schema),
{:ok, final_data} <- Skema.transform(cast_data, transform_schema) do
{:ok, final_data}
end
# Or use the combined function
case Skema.cast_and_validate(raw_data, schema) do
{:ok, data} -> IO.puts("Data is valid")
{:error, errors} -> IO.puts(inspect(errors))
end
Transformation Features
Transform allows you to modify data after casting and validation:
transform_schema = %{
email: [into: &String.downcase/1],
full_name: [
into: fn _value, data ->
"#{data.first_name} #{data.last_name}"
end
],
user_id: [as: :id, into: &generate_uuid/1]
}
Transformation Options
into
- Function to transform the field valueas
- Rename the field in the output
Function Types
# Simple transformation
[into: &String.upcase/1]
# Access to all data
[into: fn value, data -> transform_with_context(value, data) end]
# Module function
[into: {MyModule, :transform_field}]
# Error handling
[into: fn value ->
if valid?(value) do
{:ok, normalize(value)}
else
{:error, "invalid value"}
end
end]
API Differences
- cast/2 - Type conversion only, returns
{:ok, data}
or{:error, result}
- validate/2 - Rule checking only, returns
:ok
or{:error, result}
- transform/2 - Data transformation, returns
{:ok, data}
or{:error, result}
- cast_and_validate/2 - Combined cast + validate, returns
{:ok, data}
or{:error, errors}
Summary
Functions
Cast data to proper types according to schema.
Cast and validate data with given schema.
Transform data according to schema transformation rules.
Validate data according to schema rules.
Functions
@spec cast(data :: map(), schema :: map() | module()) :: {:ok, map()} | {:error, %Skema.Result{ errors: term(), params: term(), schema: term(), valid?: term(), valid_data: term() }}
Cast data to proper types according to schema.
Returns {:ok, data}
if casting succeeds, {:error, result}
otherwise.
@spec cast_and_validate(data :: map(), schema :: map() | module()) :: {:ok, map()} | {:error, errors :: map()}
Cast and validate data with given schema.
Returns {:ok, data}
if both casting and validation succeed,
{:error, errors}
otherwise.
@spec transform(data :: map(), schema :: map()) :: {:ok, map()} | {:error, %Skema.Result{ errors: term(), params: term(), schema: term(), valid?: term(), valid_data: term() }}
Transform data according to schema transformation rules.
Returns {:ok, data}
if transformation succeeds, {:error, result}
otherwise.
@spec validate(data :: map(), schema :: map() | module()) :: :ok | {:error, %Skema.Result{ errors: term(), params: term(), schema: term(), valid?: term(), valid_data: term() }}
Validate data according to schema rules.
Returns :ok
if validation succeeds, {:error, result}
otherwise.