zoedsoupe
Hello forum!
I am excited to share Peri, a schema validation library for Elixir, designed to simplify and enhance your data validation processes. Inspired by Clojure’s Plumatic Schema, Peri brings a robust and flexible solution to the Elixir ecosystem.
What is Peri?
Peri is a library that focuses on validating raw maps and supports nested schemas, optional fields, custom validations, and a variety of data types. It provides detailed error reporting to help you debug and handle invalid data effectively.
Key Features:
- Simple and Nested Schema Validation: Easily validate both flat and deeply nested schemas. Define your data structures in a clear and concise manner.
- Optional and Required Fields: Specify which fields are optional and which are required. Ensure your data meets the expected criteria.
- Custom Validations: Implement custom validation functions for complex rules specific to your application.
- Support for Various Data Types: Validate strings, integers, floats, booleans, atoms, tuples, lists, and more.
- Detailed Error Reporting: Receive clear and informative error messages to quickly identify and resolve issues in your data.
Example Usage:
Here’s a quick example to showcase how easy it is to define and validate a schema using Peri:
defmodule MySchemas do
import Peri
defschema :user, %{
name: :string,
age: :integer,
email: {:required, :string},
address: %{
street: :string,
city: :string
},
tags: {:list, :string},
role: {:enum, [:admin, :user, :guest]},
geolocation: {:tuple, [:float, :float]},
rating: {:custom, &validate_rating/1}
}
defp validate_rating(n) when n < 10, do: :ok
defp validate_rating(_), do: {:error, "invalid rating"}
end
user_data = %{name: "John", age: 30, email: "john@example.com", address: %{street: "123 Main St", city: "Somewhere"}, tags: ["science", "funky"], role: :admin, geolocation: {12.2, 34.2}, rating: 9}
case MySchemas.user(user_data) do
{:ok, valid_data} -> IO.puts("Data is valid!")
{:error, errors} -> IO.inspect(errors, label: "Validation errors")
end
In this example, we define a user schema with various fields, including nested structures, required fields, and custom validations. Peri makes it straightforward to ensure that your data conforms to these definitions.
Getting Started:
To start using Peri, add it to your mix.exs dependencies:
def deps do
[
{:peri, "~> 0.2"}
]
end
Then run mix deps.get to fetch and compile the dependency.
Documentation and Resources:
- GitHub Repository: Peri on GitHub
- Official Documentation: HexDocs for Peri
Contributing:
I welcome feedback, suggestions, and contributions from the community. If you find any issues or have ideas for improvements, please check out the contributing guidelines on GitHub.
Why Use Peri?
Peri is designed to integrate seamlessly into your Elixir projects, providing a powerful and flexible tool for schema validation. Whether you are dealing with simple data structures or complex nested schemas, Peri offers a clean and efficient solution.
I hope you find Peri useful for your Elixir applications. Feel free to share your experiences, ask questions, and contribute to the project.
Happy coding!
Trending in Announcing
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #elixirconf-us
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Exadra37
Peri looks interesting, and I may consider using it instead of Norm to define my Typed Contracts in the Elixir Scribe tool.
In your opinion what are the pros and cons of Peri when compared with Norm?
zoedsoupe
Thanks for the comment! I’m following the Elixir Scribe project, so it would be a pleasure to contribute it, even indirectly.
So Peri and Norm want to tackle the same problem, but the way each one achieve this is very different.
Norm focus in DSL based on macros for type safe guarantee, and go beyond that, provided native custom validations and generation for your already defined schema.
Peri on the other hand, os very recent and the main focus is to define schemas based on raw elixir data structures. No macros, no structs, no magical stuff, only the old good way to recurse into a schema and enforce structure, type casting or custom validations.
I was thought to be less complex in comparison of Ecto schemaless changesets and the cost is that the library is so simple but also very powerful.
When comparing directly with Norm i can see some pros:
But there are some cons as the Peri just was released 4 days ago haha.
In general these are my thinkings. Peri is ideal for flexible and direct schema structure and enforcement while Norm will shine on data generation.
Exadra37
This is more then I expected as an answer. Tank you very much
Wow, glad to meet one of the followers
Very awesome launch. Looks impressive.
Regarding the cons I will ad a few minor ones:
MySchema.user!(attrs)conforms?/1to later check if the schema is still valid. This may not be necessary ifMySchema.user(attrs)cannot be modified directly, like we can do with structs.D4no0
If we compare to other tools on the market, what is the advantage of your library over something like nimble_options?
zoedsoupe
Sure, it makes sense! I’ll add it to the new release.
I don’t know if I correctly understood this issue. Could you give me a more concrete example? As I know there’s no way to modify the schema function to validate directly.
zoedsoupe
Peri can be very similar to nimble_options, the difference though is that nimble_options only work with keyword lists while Peri works with ANY Elixir data structure or type.
Peri doesn’t have a native good handler for keyword lists though, this is exactly what I’m implementing right now
I really like the way nimble_options validates the structure recursively, so I borrowed to provide meaningful and descriptive error trees.
zoedsoupe
Hey @here, I want to share with you the new release of Peri, changes are:
conforms?/1function to know if a data matches some schemasolnic
YAY! More schema validations in Elixir - great to see this! I’m also working on a similar lib called Drops right here
solnic/drops. Would be great to compare our approaches. I also thought about not using macros and keep it simple but in my experience defining large schemas w/o DSLs gets messy quickly, that’s why I built a DSL.
zoedsoupe
Hey, I do admire the drops library! I was very excited when you announced it! But for some use cases can be very clunky and complex to define a custom DSL for schema conformation. So i did a comparison between drops and peri:
Comparison of Peri and Drops Approaches
Overview
Peri and Drops are two libraries for defining and conforming schemas in Elixir, each with its own unique features and design philosophies. Here’s a detailed comparison between the two:
Simplicity and Flexibility
Peri:
Drops:
Drops.Contractmodule, with clear differentiation between required and optional keys.Use Cases
Peri:
Drops:
Examples
Peri Example:
Drops Example:
Conclusion
Peri keeps schema definitions simple and flexible, making it ideal for projects requiring dynamic and extensible validation logic. Drops, on the other hand, provides a more structured approach with rich predefined types and validation rules, making it suitable for projects where type safety and predefined validation logic are paramount.
Both libraries offer powerful validation capabilities, and the choice between them depends on the specific needs of the project and the preferences of the development team.
Also, given a more complex example of schema in peri, I would like to translate it to drops, what do you think?
This schema demonstrates:
• Conditional Type: score is validated as an integer if it’s greater than 100, otherwise as a float.
• Either Type: country can be either a string or an atom.
• One-of Type: settings can be either a map or a list.
• Enum Type: role and preferences.theme must be one of the specified values.
cmo
I think this is missing from the docs. It is an odd validation.