# RequestValidator
A blazing fast request validator for your phoenix app, which validates a request body before hitting the request handler in the controller.
## Installation
The package can be installed by adding `request_validator` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:request_validator, "~> 0.2.0"}
]
end
```
## Basic Usage
```elixir
defmodule App.UserController do
use AppWeb, :controller
plug Request.Validation.Plug, %{
login: App.Requests.Login,
register: App.Requests.Registration
}
def login(conn, params) do
...
end
def register(conn, params) do
...
end
end
defmodule App.Requests.Registration do
use Request.Validator
@behaviour Request.Validator
@impl Request.Validator
@spec rules(Plug.Conn.t()) :: map()|keyword()
def rules(_) do
%{
"email" => [:required, :email],
"name" => [:required, :string],
"password" => [:required, :string],
"age" => [:required, :numeric, {:min, 18}]
}
end
@impl Request.Validator
@spec authorize(Plug.Conn.t()) :: boolean()
def authorize(_), do: true
end
defmodule App.Requests.Login do
use Request.Validator
@behaviour Request.Validator
@impl Request.Validator
@spec rules(Plug.Conn.t()) :: map()|keyword()
def rules(_) do
%{
"email" => [:required, :email],
"password" => [:required, :string]
}
end
@impl Request.Validator
@spec authorize(Plug.Conn.t()) :: boolean()
def authorize(_), do: true
end
```
Full documentation can be found at [https://hexdocs.pm/request_validator](https://hexdocs.pm/request_validator).
## Custom Error Messages
In most cases you will probably specify your custome error messages in a language file with the help of [gettext](https://hexdocs.pm/gettext/). First of all, you will need to provide your own translator module.
```elixir
# lib/gettext.ex
defmodule App.Gettext do
@moduledoc false
use Gettext, otp_app: :web_app
end
# lib/validations/messages.ex
defmodule App.Validation.Messages do
@moduledoc false
use Request.Validator.Messages, gettext: App.Gettext
end
# config/config.exs
use Mix.Config
config :request_validator, :translator, App.Validation.Messages
```
## Custom Validation Rules
This library provides a variety of helpful rules, however, you might want to define some rules to house your validation logic. To achieve this, you need to create your own rules and validation messages module, see example/steps below;
```elixir
# lib/validations/rules.ex
defmodule App.Validation.Rules do
use Request.Validator.Rules
use App.Repo
alias App.Repo
def exists(value, {model, field}, fields) do
from model, where: [{field, value}]
|> Repo.exists
end
end
# lib/validations/messages.ex
defmodule App.Validation.Messages do
@moduledoc false
use Request.Validator.Messages, gettext: App.Gettext
...
def exists(attr, params) do
dgettext("validations", "This %{field} doesn't exists.", field: attr)
end
end
```
After the modules have been defined you will to set some configs to override the default modules used by the library.
```elixir
# config/config.exs
use Mix.Config
config :request_validator,
rules: App.Validation.Rules,
translator: App.Validation.Messages
```
After adding the rule which is a method, then you can make use of the rule in any of your request validator module.
```elixir
defmodule App.Requests.CourseRegistration do
use Request.Validator
@behaviour Request.Validator
@impl Request.Validator
@spec rules(Plug.Conn.t()) :: map()|keyword()
def rules(_) do
%{
"email" => [:required, :email],
"name" => [:required, :string],
"age" => [:required, :numeric, {:min, 18}],
"course" => [:required, :string, {:exists, {App.Course, :id}}]
}
end
@impl Request.Validator
@spec authorize(Plug.Conn.t()) :: boolean()
def authorize(_), do: true
end
```
## Rules
Below is a list of all available validation rules and their function:
### email
The field under validation must be formatted as an e-mail address
### {gt, *field*}
The field under validation must be greater than the given field. The two fields must be of the same type
### {lt, *field*}
The field under validation must be less than the given *field*. The two fields must be of the same type
### {max, *value*}
The field under validation must be less than or equal to a maximum *value*. Supported types are strings, numerics and list.
### {min, *value*}
The field under validation must have a minimum *value*. Supported types are strings, numerics and list.
### numeric
The field under validation must be numeric.
### required
The field under validation must be present in the input data and not empty. A field is considered "empty" if one of the following conditions are true:
- The value is nil.
- The value is an empty string.
- The value is an empty list or map.
### string
The field under validation must be a string.
## TODOS
- [ ] Include more validation rules
- [ ] Norm validation support
- [ ] Ecto schema support
## License
RequestValidator is released under the MIT License - see the [LICENSE](LICENSE) file.