Magik.Contract (Magik v0.9.0) View Source

validate contract schema

Support validation

Type

Support built-in types;

  • boolean
  • integer,
  • float
  • number - string or integer
  • string
  • tuple
  • map
  • array
  • list
  • atom
  • function
  • keyword
  • struct
  • array of type

Example:

Magik.Contract.validate(%{name: "Bluz"}, %{name: [type: :string]})
Magik.Contract.validate(%{id: 123}, %{name: [type: :integer]})
Magik.Contract.validate(%{id: 123}, %{name: [type: {:array, :integer}]})
Magik.Contract.validate(%{user: %User{}}, %{user: [type: User]})
Magik.Contract.validate(%{user: %User{}}, %{user: [type: {:array: User}]})

Required

Magik.Contract.validate(%{name: "Bluz"}, %{name: [type: :string, required: true]})

Allow nil

Magik.Contract.validate(
                      %{name: "Bluz", email: nil},
                      %{
                        name: [type: :string],
                        email: [type: string, allow_nil: false]
                       })

Inclusion/Exclusion

Magik.Contract.validate(
                %{status: "active"},
                %{status: [type: :string, in: ~w(active in_active)]}
               )

Magik.Contract.validate(
                %{status: "active"},
                %{status: [type: :string, not_in: ~w(banned locked)]}
               )

Format

Validate string against regex pattern

Magik.Contract.validate(
              %{email: "Bluzblu@gm.com"},
              %{name: [type: :string, format: ~r/.+?@.+.com/]
              })

Number

Validate number value

Magik.Contract.validate(
              %{age: 200},
              %{age: [type: :integer, number[greater_than: 0, less_than: 100]]
              })

Support conditions

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

Length

Check length of list, map, string, keyword, tuple Supported condtions are the same with Number check

Magik.Contract.validate(
              %{title: "Hello world"},
              %{age: [type: :string, length: [min: 10, max: 100]]
              })

Custom validation function

Invoke given function to validate value. The function signature must be

func(field_name ::(String.t() | atom()), value :: any(), all_params :: map()) :: :ok | {:error, message}
Magik.Contract.validate(
              %{email: "blue@hmail.com"},
              %{email: [type: :string, func: &validate_email/3]})

def validate_email(_name, email, _params) do
  if Regex.match?(~r/[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,4}$/, email) do
    :ok
  else
    {:error, "not a valid email"}
  end
end

Nested map

Nested map declaration is the same.

data =   %{name: "Doe John", address: %{city: "HCM", street: "NVL"} }
schema = %{
    name: [type: :string],
    address: [type: %{
            city: [type: :string],
            street: [type: :string]
          }]
  }
Magik.Contract.validate(data, schema)

Nested list

data =   %{name: "Doe John", address: [%{city: "HCM", street: "NVL"}] }
address = %{ city: [type: :string],  street: [type: :string] }
schema = %{
    name: [type: :string],
    address: [type: {:array, address}]
   }
Magik.Contract.validate(data, schema)

Link to this section Summary

Link to this section Functions