Para (Para v0.2.1)
Para is an Elixir library that provides structured and declarative way to parse and validate parameters.
Para uses Ecto under the hood and therefore inherits most of its utilities such as changeset and built-in validators.
Usage
Let's imagine that you have a controller named Web.UserController
and
wanted to validate the parameters for its :create
and :update
actions
First, let's define your parameters schema
defmodule Web.UserPara do
use Para
validator :create do
required :name, :string
required :age, :integer
required :email, :string
optional :phone, :string
end
validator :update do
required :name, :string
required :age, :integer
required :email, :string
optional :phone, :string
end
end
You can now use this module as a validator in your controller
defmodule Web.UserController do
use Web, :schema
alias Web.UserPara
def create(conn, params) do
with {:ok, data} <- UserPara.validate(:create, params) do
# ...
end
end
end
Inline validators
Inline validator is a convenient way to validate your fields. This is
especially useful when you need to perform some basic validation
using Ecto.Changeset
's built-in validators.
defmodule UserPara do
use Para
validator :update do
required :name, :string, validator: {:validate_length, [min: 3, max: 100]}
end
end
You can also use custom inline validators by supplying the function name
as an atom. Custom inline validator will receive changeset
and the
original params
as the arguments.
defmodule UserPara do
use Para
validator :update do
required :age, :string, validator: :validate_age
end
def validate_age(changeset, params) do
# ...
end
end
Callback validator
Sometimes, you might want to use custom validators or need to perform
additional data manipulations. For this, you can use the callback/1
macro.
The callback/1
macro will always be the last function to be called
after the validator has parsed and validated the parameters.
defmodule Web.UserPara do
use Para
validator :create do
required :name, :string
required :age, :integer
required :email, :string
optional :phone, :string
callback :create_validators
end
def create_validators(changeset, params) do
changeset
|> format_email(params)
|> format_phone(params)
|> validate_age()
end
def format_email(changeset, params) do
# ...
end
def format_phone(changeset, params) do
# ...
end
def validate_age(changeset) do
# ...
end
end
Link to this section Summary
Functions
Define custom callback to perform any additional parsing or validation to the processed changeset or parameters
Define an embedded array of maps field
Define an embedded map field
Define an optional field.
Define a required field.
Define a validator schema with an action name and field definitions.
Link to this section Types
Specs
t() :: {:ok, map()} | {:error, Ecto.Changeset.t()}
Link to this section Functions
Define custom callback to perform any additional parsing or validation to the processed changeset or parameters
Define an embedded array of maps field
Define an embedded map field
Define an optional field.
Similar to required/3
, it also accepts the same Options
Define a required field.
Options
:default
- Assign a default value if the not set by input parameters:validator
- Define either one of the built-in Ecto.Changeset's validators or use your own custom inline validator. Refer: Custom inline validator:droppable
- Drop the field when the key doesn't exist in parameters. This is useful when you need to perform partial update by leaving out certain fields.
Custom inline validator
You can define your own validator as such:
def validate_country(changeset, field) do
# ...
end
Then use it as an inline validator for your field
validator :create do
required :country, :string, [validator: :validate_country]
end
Define a validator schema with an action name and field definitions.
This will generate a new function called validate/2
with the action name
and params
as the arguments.
iex> defmodule UserPara do
...> use Para
...>
...> validator :create do
...> required :name
...> end
...> end
...>
...> UserPara.validate(:create, %{"name" => "Syamil MJ"})
{:ok, %{name: "Syamil MJ"}}