Parsing and Validating Data in Elixir

In the enchanting world of Elixir programming, data validation is a quest every developer embarks on. It’s a journey through the land of schemas, types, and constraints, ensuring data integrity and correctness. Today, we’ll explore four powerful artifa…


This content originally appeared on DEV Community and was authored by Zoey de Souza Pessanha

In the enchanting world of Elixir programming, data validation is a quest every developer embarks on. It's a journey through the land of schemas, types, and constraints, ensuring data integrity and correctness. Today, we'll explore four powerful artifacts: Ecto, Norm, Drops, and Peri. Each of these tools offers unique powers for taming your data. We'll delve into their strengths, use cases, and compare them to help you choose the right one for your quest.

The Quest: Parse, Don't Validate

Before we embark on our journey, let's discuss a guiding principle in functional programming: Parse, Don't Validate. This pattern emphasizes transforming data into a well-defined structure as early as possible. By doing so, you avoid scattered, ad-hoc validation throughout your codebase, leading to clearer, more maintainable code. It's like casting a spell to organize the chaos of raw data into a neat, structured form.

The Artifacts

1. Ecto

Ecto is a robust toolkit primarily designed for interacting with databases. However, it also offers powerful capabilities for embedded schemas and schemaless changesets, making it versatile for data validation.

Embedded Schemas

Ecto allows defining schemas that don't map to a database table, ideal for validating nested data structures.

defmodule User do
  use Ecto.Schema

  embedded_schema do
    field :name, :string
    field :email, :string
  end
end

def changeset(data) do
  %User{}
  |> Ecto.Changeset.cast(data, [:name, :email])
  |> Ecto.Changeset.validate_required([:name, :email])
end

Schemaless Changesets

For dynamic data, Ecto provides schemaless changesets, offering flexibility at the cost of increased complexity.

def changeset(data) do
  Ecto.Changeset.cast({%{}, %{name: :string, email: :string}}, data, [:name, :email])
  |> Ecto.Changeset.validate_required([:name, :email])
end

2. Norm

Norm focuses on defining and conforming to data structures with custom predicates, offering a clean syntax and powerful validation.

defmodule User do
  import Norm

  defschema do
    schema(%{
      name: spec(is_binary()),
      age: spec(is_integer() and &(&1 > 18))
    })
  end
end

Norm.conform(%{name: "Jane", age: 25}, User.schema())
# => {:ok, %{name: "Jane", age: 25}}

3. Drops

Drops is a newer library that provides a rich set of tools for defining and validating schemas, leveraging Elixir's type system.

defmodule UserContract do
  use Drops.Contract

  schema do
    %{
      required(:name) => string(:filled?),
      required(:age) => integer(gt?: 18)
    }
  end
end

UserContract.conform(%{name: "Jane", age: 21})
# => {:ok, %{name: "Jane", age: 21}}

4. Peri

Peri is inspired by Clojure's Plumatic Schema, focusing on validating raw maps with nested schemas and optional fields. It's designed to be powerful yet simple, embracing the "Parse, Don't Validate" pattern.

defmodule MySchemas do
  import Peri

  defschema :user, %{
    name: :string,
    age: :integer,
    email: {:required, :string},
    role: {:enum, [:admin, :user]}
  }

  defschema :profile, %{
    user: {:custom, &MySchemas.user/1},
    bio: :string
  }
end

MySchemas.user(%{name: "John", age: 30, email: "john@example.com", role: :admin})
# => {:ok, %{name: "John", age: 30, email: "john@example.com", role: :admin}}

MySchemas.user(%{name: "John", age: "thirty", email: "john@example.com"})
# => {:error, [%Peri.Error{path: [:age], message: "expected integer received \"thirty\""}]}

Conditional and Composable Types in Peri

Peri shines with its support for conditional and composable types, making it a powerful tool for complex validation scenarios.

defmodule AdvancedSchemas do
  import Peri

  defschema :user, %{
    name: :string,
    age: {:cond, &(&1 >= 18), :integer, :nil},
    email: {:either, {:string, :nil}},
    preferences: {:list, {:oneof, [:string, :atom]}}
  }
end

AdvancedSchemas.user(%{name: "Alice", age: 25, email: nil, preferences: ["coding", :reading]})
# => {:ok, %{name: "Alice", age: 25, email: nil, preferences: ["coding", :reading]}}

AdvancedSchemas.user(%{name: "Bob", age: 17})
# => {:ok, %{name: "Bob", age: 17, email: nil, preferences: nil}}

Conclusion

Each of these tools offers unique advantages and caters to different needs:

  • Ecto is great for data associated with databases but can handle schemaless and embedded data structures too.
  • Norm provides a clean and powerful way to define and validate data structures.
  • Drops leverages Elixir's type system and offers rich schema definitions and validations.
  • Peri emphasizes simplicity and power, supporting complex types and conditional validations.

By understanding the strengths and weaknesses of each, you can choose the right tool for your data validation needs in Elixir. Happy coding, fellow sorcerers of Elixiria!

References

Feel free to dive into the source code and contribute to these projects to make Elixiria an even more magical place!


This content originally appeared on DEV Community and was authored by Zoey de Souza Pessanha


Print Share Comment Cite Upload Translate Updates
APA

Zoey de Souza Pessanha | Sciencx (2024-06-18T22:40:53+00:00) Parsing and Validating Data in Elixir. Retrieved from https://www.scien.cx/2024/06/18/parsing-and-validating-data-in-elixir/

MLA
" » Parsing and Validating Data in Elixir." Zoey de Souza Pessanha | Sciencx - Tuesday June 18, 2024, https://www.scien.cx/2024/06/18/parsing-and-validating-data-in-elixir/
HARVARD
Zoey de Souza Pessanha | Sciencx Tuesday June 18, 2024 » Parsing and Validating Data in Elixir., viewed ,<https://www.scien.cx/2024/06/18/parsing-and-validating-data-in-elixir/>
VANCOUVER
Zoey de Souza Pessanha | Sciencx - » Parsing and Validating Data in Elixir. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/06/18/parsing-and-validating-data-in-elixir/
CHICAGO
" » Parsing and Validating Data in Elixir." Zoey de Souza Pessanha | Sciencx - Accessed . https://www.scien.cx/2024/06/18/parsing-and-validating-data-in-elixir/
IEEE
" » Parsing and Validating Data in Elixir." Zoey de Souza Pessanha | Sciencx [Online]. Available: https://www.scien.cx/2024/06/18/parsing-and-validating-data-in-elixir/. [Accessed: ]
rf:citation
» Parsing and Validating Data in Elixir | Zoey de Souza Pessanha | Sciencx | https://www.scien.cx/2024/06/18/parsing-and-validating-data-in-elixir/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.