Typeid

hex.pm versionHex Docs

An Elixir implementation of TypeID.

TypeIDs are a modern, type-safe, globally unique identifier based on the upcoming UUIDv7 standard. They provide a ton of nice properties that make them a great choice as the primary identifiers for your data in a database, APIs, and distributed systems. Read more about TypeIDs in the specification.

Installation

Requires Elixir 1.14 or later.

def deps do
[
{:elixir_typeid, "~> 0.3"}
]
end

Intro

The Ecto and Jason extensions are generated when their optional dependencies are available while elixir_typeid is compiled. If either dependency is added later, recompile this library. The built-in JSON.Encoder implementation is generated on Elixir releases that provide the JSON module.

Usage

iex> {:ok, typeid} = Typeid.new("user")
{:ok, #Typeid<"user_01hz6wxrw2ecmtwaqhnnpr275f">}
iex> "#{typeid}"
"user_01hz6wxrw2ecmtwaqhnnpr275f"
iex> Typeid.uuid(typeid)
{:ok, #UUIDv7<018fcdce-e382-7329-ae2a-f1ad6d811caf>}
iex> Typeid.parse("user_01hz6wxrw2ecmtwaqhnnpr275f")
{:ok, #Typeid<"user_01hz6wxrw2ecmtwaqhnnpr275f">}
iex> Typeid.valid?(typeid)
true

Use with Ecto

In usual we use TypeID to generate the primary key with Ecto schema, define Typeid type within @primary_key:

defmodule User do
use Ecto.Schema
@primary_key {:id, Typeid, autogenerate: true, type: "user"}
schema "user" do
field(:name, :string)
end
end

or define Typeid type in a primary key field of a schema:

defmodule User do
use Ecto.Schema
@primary_key false
schema "user" do
field(:user_id, Typeid, autogenerate: true, primary_key: true, type: "user")
field(:name, :string)
end
end

If type: "user" is not set, TypeID uses an unprefixed value (prefix: nil). The configured type must be nil, "", or a valid TypeID prefix. Ecto validates the complete TypeID and requires a configured prefix to match exactly during casting, loading, and dumping. Ecto integration requires Ecto ~> 3.5.

Use with Built-in JSON Encoding

When the built-in JSON module is available, we can encode a Typeid struct as a JSON string:

iex> {:ok, typeid} = Typeid.new("user")
iex> JSON.encode!(typeid)
"\"user_01hz6wxrw2ecmtwaqhnnpr275f\""

Use with Jason Encoding

We can simply encode a Typeid struct with Jason.

iex> typeid
#Typeid<"user_01hz6wxrw2ecmtwaqhnnpr275f">
iex> Jason.encode(%{id: typeid})
{:ok, "{\"id\":\"user_01hz6wxrw2ecmtwaqhnnpr275f\"}"}