phcurado

phcurado

Zoi - schema validation library inspired by Zod

Zoi is a new schema validation library for Elixir.

It’s inspired by Zod from the JavaScript ecosystem, bringing a similar functional API for defining, validating, transforming and coercing data, using elixir pipes for the schema definition.

Basic Example

iex> schema = Zoi.string() |> Zoi.min(3)
iex> Zoi.parse(schema, "hello")
{:ok, "hello"}
iex> Zoi.parse(schema, "hi")
{:error, [%Zoi.Error{message: "too small: must have at least 3 characters"}]}

Transformations

iex> schema = Zoi.string() |> Zoi.trim()
iex> Zoi.parse(schema, "    world    ")
{:ok, "world"}

Coercion

iex> Zoi.string() |> Zoi.parse(123)
{:error, [%Zoi.Error{message: "invalid type: must be a string"}]}
iex> Zoi.string(coerce: true) |> Zoi.parse(123)
{:ok, "123"}

Complex schemas

iex> user_schema =
...>   Zoi.object(%{
...>     name: Zoi.string() |> Zoi.min(2) |> Zoi.max(100),
...>     age: Zoi.integer() |> Zoi.min(18) |> Zoi.max(120),
...>     email: Zoi.email()
...>   })
iex> Zoi.parse(user_schema, %{name: "Alice", age: 30, email: "alice@email.com"})
{:ok, %{name: "Alice", age: 30, email: "alice@email.com"}}

There are many built in types, validations and transformations. Check out the documentation for all the possibilities.


:books: Docs: Zoi — Zoi v0.18.4
:package: Hex: zoi | Hex
:laptop: Repo:

https://github.com/phcurado/zoi

I would love to hear your feedback, thoughts and any additional features you’d like to see

Most Liked

phcurado

phcurado

v0.10 released with Phoenix form support :rocket:

Hi everyone! I finally released the 0.10 version of Zoi, now you can use your Zoi schemas directly in Phoenix forms.
This release implements the Phoenix.HTML.FormData protocol, which allows you to use Zoi.Context structs as form data sources.

Quick example:

# Define schema inline
@user_schema Zoi.object(%{
  name: Zoi.string() |> Zoi.min(3),
  email: Zoi.email()
}) |> Zoi.Form.prepare()

# Parse and render (just like changesets!)
ctx = Zoi.Form.parse(@user_schema, params)
form = to_form(ctx, as: :user)

socket |> assign(:form, form)

# Use in your forms
~H"""
<.form for={@form} phx-submit="save">
  <.input field={@form[:name]} label="Name" />
  <.input field={@form[:email]} label="Email" />
  <div>
    <.button>Save</.button>
  </div>
</.form>
"""

Guides

Release v0.10: zoi | Hex

phcurado

phcurado

Zoi is reaching 10k downloads on hex.pm :star:

I would like to thank everyone who has used and supported this library. Every feedback has been taken seriously and helped to improve this project.

These are the main features that have been added based on feedback:

  • Zoi.describe/2: function for generating documentation based on descriptions your schema.
  • Zoi.Form: module that integrates with Phoenix forms.
  • Zoi.JSONSchema: Converting Zoi schemas to JSON Schema (for API documentation, validation, etc.).
  • Zoi.Struct: A helper module to define and validate structs using Zoi schemas
  • Zoi.Schema: Utilities for traversing and transforming Zoi schemas.

And many more added into the project’s internals!

I created a blog post where I walk through some of the Zoi features and the reason behind creating this library.

Check it out here.

Don’t forget to check the git repo and if you have any feedback or suggestions, feel free to open an issue or a PR.

phcurado

phcurado

New 0.15.0 release

Hi everyone!

This new version brings more types and more flexibility with elixir typespecs.

New typespec keyword:

Zoi.integer(gte: 0, typespec: quote(do: non_neg_integer()))
Zoi.any(typespec: quote(do: pos_integer()))

If you have a more complex schema which cannot be fully expressed by the Zoi inferred typespec, you can use this approach to express your type the way you want.

New types

  • Zoi.pid/1 type for validating pid values
  • Zoi.module/1 type for validating module values
  • Zoi.reference/1 type for validating reference values
  • Zoi.port/1 type for validating port values
  • Zoi.macro/1 type for validating quoted expressions (Macro.t())
  • Zoi.function/1 type for validating function values with optional arity constraint
  • Zoi.json/1 type for validating any JSON-compatible value (string, number, boolean, null, array, or object with string keys)

Zoi.map/2 is now preferred over Zoi.object/2

This was a feedback from @jam and I was slowly improving the map type to align more with the Elixir native map. Now you can express maps the same as we could express objects with some extras, examples:

# Map with string keys and values are integers
Zoi.map(Zoi.string(), Zoi.integer())

# Map with any key and values
Zoi.map()

# A map the follows a given structure (same as object):
Zoi.map(%{
  name: Zoi.string(),
  age: Zoi.integer() |> Zoi.optional()
})

no changes were made in Zoi.object/2, it uses a structured Zoi.map/2 under the hood and I don’t plan to deprecate this type.

Zoi is 43% faster when parsing

I decided to do some benchmarks and found some areas for improvements. Zoi is even faster when parsing deeply nested data structure. Now Zoi parses 43% faster compared to the previous implementation. You can run the benchmarks by following the documentation here.


:books: Docs: hexdocs.pm/zoi
:package: Hex: hex.pm/packages/zoi
:laptop: Repo: github.com/phcurado/zoi

Where Next?

Popular in Announcing Top

tmbb
I’ve published the first version of my Makeup library. It’s a syntax highlighter for Elixir in the spirit of Pygments, Currently it highl...
New
bryanjos
Hi, I just published version 0.23.0 of Elixirscript. https://github.com/bryanjos/elixirscript/blob/master/CHANGELOG.md Most of the chan...
New
zorbash
I created Kitto a framework for dashboards inspired by Dashing. The distributed characteristics of Elixir and the low memory footprint...
New
kip
ex_cldr provides localisation and internationalisation support based upon the data from the Unicode CLDR project. Unicode released CLDR ...
407 13056 120
New
nikokozak
Hello all, I’ve been working on Svonix - a library for quickly integrating Svelte components into Phoenix views. It’s a much-needed succ...
New
michalmuskala
Another small library today. PersistentEts Hex: persistent_ets | Hex GitHub: GitHub - michalmuskala/persistent_ets · GitHub Ets table ...
New
achempion
Hi, I would like to tell about my initiative to further maintain and develop Waffle project which is the fork of Arc library. The progre...
New
woylie
I released Doggo, a collection of unstyled Phoenix components. https://github.com/woylie/doggo Features Unstyled Phoenix components....
New
dbern
I’m excited to announce that TaxJar has developed and open-sourced DateTimeParser. We developed it because we found a need to parse user ...
New
pkrawat1
Hey guyz We at @aviabird are working on a payment library in elixir/phoenix. We are targeting March 2018 to add 56 Gateways to it. Have...
New

Other popular topics Top

Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43806 214
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31307 143
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36432 110
New
New

We're in Beta

About us Mission Statement