Para: Parse and Validate Parameters
Strongly-typed languages rely on a few tricks to ensure safety and reliability of its system. With Elixir, one of the most common practices is to enforce types using pattern matchings or guard clauses.
I recently covered a few best practices to consider when using this strategy in my previous article.
However, as our system gets more complex we will often find the task of manually parsing and validating parameters to be somewhat tedious. The sentiment is in fact shared by many, that we can find quite a few libraries that attempt to help solve this problem. Arguably, like many parts of Elixir they were inspired by Rails - case in point: StrongParameters.
What is Para?
Para provides a declarative way to parse and validate parameters. It uses Ecto under the hood, loosely adhering to most of its common public interfaces. The main objective is to simplify the task of building the structure around parsing and validating parameters.
Para can be used within any layers of an Elixir application. Here’s how it might look like for a typical Phoenix application:
The library is available on GitHub and Hex.pm.
So why Para?
Most Elixir developers should be familiar enough with Ecto’s DSL, so using Para should be quite straightforward. What sets it apart are mainly in terms of simpler code structure and useful shortcuts to speed-up development.
Let’s dive a little deeper into some of its features.
1. Contextual
Para allows developers to group a set of actions that belongs to the same context into a single module. For example, when you have a controller named UserController
, it would make sense to have a single UserPara
module to handle all the validations.
Here’s an example:
defmodule UserPara do
use Para
# Validation for :create action
validator :create do
required :name
required :age, :integer
end
# Validation for :update action
validator :update do
required :name, :string, droppable: true
required :age, :string, droppable: true
end
end
2. Powerful and flexible
Para includes an inline validator feature which simplifies the effort to perform additional validation to any specific field. In addition to supporting all of Ecto’s validate_*
functions, it can also be used with any custom function.
validator :test do
required :name, :string, validator: {:validate_length, [max: 128]}
required :email, :float, validator: {:validate_email, "~r/@/"}
required :type, :string, validator: :validate_material
end
def validate_material(changeset, params) do
# ...
end
If that’s not enough, we can also use a custom callback function for each validator to perform any additional data manipulation.
validator :test do
required :address_line_1
required :address_line_2
required :city
required :zipcode
required :state
required :country
callback :validate_address
end
def validate_address(changeset, params) do
# ...
end
What’s Next?
Para is still a new library so we need your help to make it better. If you found any issues or would like to suggest a new feature, please feel free to open a new thread on the GitHub repo.