https://github.com/lob/litmus
Data schema validation in Elixir
https://github.com/lob/litmus
elixir elixir-lang parameters plug schema validation validator
Last synced: 26 days ago
JSON representation
Data schema validation in Elixir
- Host: GitHub
- URL: https://github.com/lob/litmus
- Owner: lob
- License: mit
- Created: 2018-07-17T17:25:23.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2022-03-18T23:40:01.000Z (about 3 years ago)
- Last Synced: 2025-04-17T13:07:32.012Z (about 2 months ago)
- Topics: elixir, elixir-lang, parameters, plug, schema, validation, validator
- Language: Elixir
- Size: 1.58 MB
- Stars: 34
- Watchers: 59
- Forks: 4
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Litmus
[](https://hex.pm/packages/litmus)
[](https://hexdocs.pm/litmus/Litmus.html)
[](https://travis-ci.org/lob/litmus)Data validation in Elixir
## Installation
The package can be installed by adding `litmus` to your list of dependencies in
`mix.exs`:```elixir
def deps do
[
{:litmus, "~> 1.0.2"}
]
end
```## Usage
Litmus validates data against a predefined schema with the `Litmus.validate/2`
function.If the data is valid, the function returns `{:ok, data}`. The data returned
will be coerced according to the provided schema.If the data passed does not follow the rules defined in the schema, the
function returns `{:error, error_message}`. It will also return an error when
receiving a field that has not been specified in the provided schema.```elixir
schema = %{
"id" => %Litmus.Type.Any{
required: true
},
"username" => %Litmus.Type.String{
min_length: 6,
required: true
},
"pin" => %Litmus.Type.Number{
min: 1000,
max: 9999,
required: true
},
"new_user" => %Litmus.Type.Boolean{
truthy: ["1"],
falsy: ["0"]
},
"account_ids" => %Litmus.Type.List{
max_length: 3,
type: :number
},
"remember_me" => %Litmus.Type.Boolean{
default: false
}
}params = %{
"id" => 1,
"username" => "user@123",
"pin" => 1234,
"new_user" => "1",
"account_ids" => [1, 3, 9]
}Litmus.validate(params, schema)
# => {:ok,
# %{
# "id" => 1,
# "new_user" => true,
# "pin" => 1234,
# "username" => "user@123",
# "account_ids" => [1, 3, 9],
# "remember_me" => false
# }
# }Litmus.validate(%{}, schema)
# => {:error, "id is required"}
```## Supported Types
Litmus currently supports the following types.
* `Litmus.Type.Any`
* `Litmus.Type.Boolean`
* `Litmus.Type.DateTime`
* `Litmus.Type.List`
* `Litmus.Type.Number`
* `Litmus.Type.String`## Plug Integration
Litmus comes with a Plug for easy integration with Plug's built-in router. You can automatically validate query
parameters and body parameters by passing the `litmus_query` and `litmus_body` private options to each route. When
declaring the plug you must include a `on_error/2` function to be called when validation fails. It is recommended that
you initialize this Plug between the `:match` and `:dispatch` plugs. If you want processing to stop on a validation
error, be sure to halt the request with `Plug.Conn.halt/1`.#### Example
```elixir
defmodule MyRouter do
use Plug.Routerplug(Plug.Parsers, parsers: [:urlencoded, :multipart])
plug(:match)
plug(Litmus.Plug, on_error: &__MODULE__.on_error/2)
plug(:dispatch)
@schema %{
"id" => %Litmus.Type.Number{
required: true
}
}get "/test", private: %{litmus_query: @schema} do
Plug.Conn.send_resp(conn, 200, "items")
endpost "/test", private: %{litmus_body: @schema} do
Plug.Conn.send_resp(conn, 200, "items")
enddef on_error(conn, error_message) do
conn
|> Plug.Conn.send_resp(400, error_message)
|> Plug.Conn.halt()
end
end
```