Magik.Schema (Magik v0.10.0) View Source

This is only a specification to define a schema to use with Magik.Params.cast and Magik.Contract.validate

Schema is just a map or keyword list that follow some simple conventions. Map's key is the field name and the value is a keyword list of field specifications.

Example

%{
  name: [type: :string, format: ~r/{4}/],
  age: [type: :integer, number: [min: 15, max: 50]].
  skill: [type: {:array, :string}, length: [min: 1, max: 10]]
}

This schema define a map with a field name which type is string

I. Field type

Built-in types

A type could be any of built-in supported types:

  • boolean
  • string | binary
  • integer
  • float
  • number (integer or float)
  • date
  • time
  • datetime | utc_datetime: date time with time zone
  • naive_datetime: date time without time zone
  • map
  • keyword
  • {array, type} array of built-in type, all item must be the same type

Other types Custom type may be supported depends on module.

Nested types Nested types could be a another schema or list of schema

%{
  user: [type: %{
      name: [type: :string]
    }]
}

Or list of schema

%{
  users: [type: {:array, %{
      name: [type: :string]
    }} ]
}

II. Field casting and default value

These specifications is used for casting data with Magik.Params.cast

1. Default value

Is used when the given field is missing or nil.

  • Default could be a value

    %{
      status: [type: :string, default: "active"]
    }
  • Or a function/0, this function will be invoke each time data is casted

    %{
      published_at: [type: :datetime, default: &DateTime.utc_now/0]
    }

2. Custom cast function

You can provide a function to cast field value instead of using default casting function by using cast_func: <function/1>

%{
    published_at: [type: :datetime, cast_func: &DateTime.from_iso8601/1]
}

III. Field validation

These validation are supported by Magik.Validator

1. Type validation

Type specification above could be used for validating or casting data.

2. Numeric validation

Support validating number value. These are list of supported validations:

  • equal_to
  • greater_than_or_equal_to | min
  • greater_than
  • less_than
  • less_than_or_equal_to | max

Define validation: number: [<name>: <value>, ...]

Example

%{
  age: [type: :integer, number: [min: 1, max: 100]]
}

3. Length validation

Validate length of supported types include string, array, map, tuple, keyword. Length condions are the same with Numeric validation

Define validation: length: [<name>: <value>, ...]

Example

%{
  skills: [type: {:array, :string}, length: [min: 0, max: 5]]
}

4. Format validation

Check if a string match a given pattern.

Define validation: format: <Regex>

Example

%{
  year: [type: :string, format: ~r/year: {4}/]
}

5. Inclusion and exclusion validation

Check if value is included or not included in given enumerable (array, map, or keyword)

Define validation: in: <enumerable> or not_in: <enumerable>

Example

%{
  status: [type: :string, in: ["active", "inactive"]],
  selected_option: [type: :integer, not_in: [2,3]]
}

6. Custom validation function

You can provide a function to validate the value.

Define validation: func: <function>

Function must be follow this signature

@spec func(value::any()) :: :ok | {:error, message::String.t()}