View Source Tarams.Schema (Tarams v1.7.1)

This is only a specification to define a schema to use with Tarams.Params.cast and Tarams.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]]
}

If you only specify type of data, you can write it shorthand style like this

%{
  name: :string,
  age: :integer,
  skill: {:array, :string}
}

i-field-type

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]
    }} ]
}

Alias Alias allow set a new key for value when using with Taram.cast

schema = %{
  email: [type: :string, as: :user_email]
}

Tarams.cast(%{email: "xx@yy.com"}, schema)
#> {:ok, %{user_email: "xx@yy.com"}}

ii-field-casting-and-default-value

II. Field casting and default value

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

1-default-value

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

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

III. Field validation

These validation are supported by Tarams.Validator

1-type-validation

1. Type validation

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

2-numeric-validation

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

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

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

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

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

Link to this section Summary

Functions

Expand short-hand type syntax to full syntax

Link to this section Functions

@spec expand(map()) :: map()

Expand short-hand type syntax to full syntax

field: :string -> field: [type: :string]
field: {:array, :string} -> field: [type: {:array, :string}]
field: %{#embedded} -> field: [type: %{#embedded}]