Valdi
View SourceA comprehensive Elixir data validation library with flexible, composable validators
Installation
The package can be installed by adding valdi to your list of dependencies in mix.exs:
def deps do
[
{:valdi, "~> 0.5.0"}
]
endDocument can be found at https://hexdocs.pm/valdi.
Features
- ✅ Type validation - validate data types including numbers, strings, lists, maps, structs, and Decimal types
- ✅ Constraint validation - validate ranges, lengths, formats, and inclusion/exclusion
- ✅ Flattened validators - use convenient aliases like
min,max,min_lengthwithout nesting - ✅ Pattern matching - efficient validation dispatch using Elixir's pattern matching
- ✅ Composable - combine multiple validations in a single call
- ✅ Backward compatible - works with existing validation patterns
- ✅ Conditional type checking - skip type validation when not needed for better performance
- ✅ List and map validation - validate collections and structured data
- ✅ Custom validators - extend with your own validation functions
- ✅ Flexible error handling - option to ignore unknown validators
Quick Start
Basic Validation
# Type validation
Valdi.validate("hello", type: :string)
#=> :ok
# Constraint validation without type checking (new!)
Valdi.validate("hello", min_length: 3, max_length: 10)
#=> :ok
# Combined validations
Valdi.validate(15, type: :integer, min: 10, max: 20, greater_than: 5)
#=> :okFlattened Validators (New!)
Instead of nested syntax:
# Old nested approach
Valdi.validate("test", type: :string, length: [min: 3, max: 10])
Valdi.validate(15, type: :integer, number: [min: 10, max: 20])Use convenient flattened syntax:
# New flattened approach
Valdi.validate("test", type: :string, min_length: 3, max_length: 10)
Valdi.validate(15, type: :integer, min: 10, max: 20)
# Mix both styles
Valdi.validate(15, min: 10, number: [max: 20])List Validation
# Validate each item in a list
Valdi.validate_list([1, 2, 3], type: :integer, min: 0)
#=> :ok
# With errors showing item indexes
Valdi.validate_list([1, 2, 3], type: :integer, min: 2)
#=> {:error, [[0, "must be greater than or equal to 2"]]}Map Validation
# Define validation schema
schema = %{
name: [type: :string, required: true, min_length: 2],
age: [type: :integer, min: 0, max: 150],
email: [type: :string, format: ~r/.+@.+/]
}
# Validate map data
Valdi.validate_map(%{name: "John", age: 30, email: "john@example.com"}, schema)
#=> :ok
Valdi.validate_map(%{name: "J", age: 30}, schema)
#=> {:error, %{name: "length must be greater than or equal to 2"}}Individual Validators
Each validator can be used independently:
Valdi.validate_type("hello", :string)
#=> :ok
Valdi.validate_number(15, min: 10, max: 20)
#=> :ok
Valdi.validate_length("hello", min: 3, max: 10)
#=> :ok
Valdi.validate_inclusion("red", ["red", "green", "blue"])
#=> :okAvailable Validators
Core Validators
type- validate data typerequired- ensure value is not nilformat/pattern- regex pattern matchingin/enum- value inclusion validationnot_in- value exclusion validationfunc- custom validation function
Numeric Validators
number- numeric constraints (nested syntax)min- minimum value (≥)max- maximum value (≤)greater_than- strictly greater than (>)less_than- strictly less than (<)
Length Validators
length- length constraints (nested syntax)min_length- minimum lengthmax_length- maximum lengthmin_items- minimum array items (alias for min_length)max_items- maximum array items (alias for max_length)
Other Validators
each- validate each item in arraysdecimal- decimal validation (deprecated, usenumberinstead)
Supported Data Types
Built-in types:
:boolean,:integer,:float,:number(int or float):string,:binary(string is binary alias):tuple,:array,:list,:atom,:function,:map:date,:time,:datetime,:naive_datetime,:utc_datetime:keyword,:decimal
Extended types:
{:array, type}- typed arrays (e.g.,{:array, :string})structmodules (e.g.,Userfor%User{}structs)
# Type validation examples
Valdi.validate(["one", "two", "three"], type: {:array, :string})
#=> :ok
Valdi.validate(%User{name: "John"}, type: User)
#=> :ok
Valdi.validate(~D[2023-10-11], type: :date)
#=> :okOptions
ignore_unknown: true- skip unknown validators instead of returning errors
Valdi.validate("test", [type: :string, unknown_validator: :value], ignore_unknown: true)
#=> :okDocumentation
For detailed documentation, examples, and API reference, visit https://hexdocs.pm/valdi.