This package provides an Ecto type for human readableĀ IDs, like user_2x2QlH09G3tPrptOPzhr5
, consisting of a string prefix plus a Base62-encoded UUIDv7.
Having different prefixes for each "ID type" makes them more readable, prevents human error, and enables features such as polymorphic lookup.
UUIDv7 generation and Base62 encode/decode are implemented in Rust using a NIF.
Inspiration for this package is taken from:
- https://danschultzer.com/posts/prefixed-base62-uuidv7-object-ids-with-ecto
- https://dev.to/stripe/designing-apis-for-humans-object-ids-3o5a
The package can be installed by adding prefixed_id
to your list of dependencies in mix.exs
:
def deps do
[
{:prefixed_id, "~> 0.1.0"}
]
end
Use PrefixedID
as the @primary_key
type in your schema, providing a prefix
:
defmodule MyApp.User do
use Ecto.Schema
@primary_key {:id, PrefixedID, prefix: "user", autogenerate: true}
...
end
If referencing a table with a PrefixedID
primary key, specify @foreign_key_type
:
defmodule MyApp.UserToken do
use Ecto.Schema
@foreign_key_type PrefixedID
...
end
To use PrefixedID
for all keys, you can define your own Schema
module:
defmodule MyApp.Schema do
defmacro __using__(opts) do
id_prefix = Keyword.fetch!(opts, :id_prefix)
quote do
use Ecto.Schema
@primary_key {:id, PrefixedID, prefix: unquote(id_prefix), autogenerate: true}
@foreign_key_type PrefixedID
@timestamps_opts [type: :utc_datetime_usec]
end
end
end
defmodule MyApp.User do
use MyApp.Schema, id_prefix: "user"
...
end