AshObjectIds (ash_object_ids v0.3.0)

View Source

A helper library for working with object IDs in Ash.

Object IDs are identifiers that are prefixed with the resource they identify. A more detailed explanation can be found in the "Designing APIs for humans" blog post.

This library provides an implementation for Ash, where the IDs are base58-encoded UUIDs with a prefix:

defmodule App.Blog.Post do
  use Ash.Resource,
    domain: App.Blog,
    data_layer: Ash.DataLayer.AshPostgres,

  # This generates a __MODULE__.Id module that's an Ash.Type.
  use AshObjectIds, prefix: "p", uuid_type: :uuid_v7

  attributes do
    object_id_primary_key()
    # ... other attributes
  end
end

Alternatively, if you want to control the module generation (or want to define it outside of the resource), then you can use AshObjectIds.Type:

defmodule App.Blog.Post.Id do
  use AshObjectIds.Type, prefix: "p", uuid_type: :uuid_v7
end

Summary

Functions

Decodes the given object ID into a string version of the UUID.

Same as map_prefixes_to_resources, but returns only the entries that contain more than resource for the given prefix.

Same as find_resource_for_prefix/2 but accepts a (valid) object ID.

Searches the given domains for the resource that matches the given object ID prefix.

Create a map of prefixes to the resources that use that prefix.

Generates an object ID primary key.

Functions

decode_object_id(id)

@spec decode_object_id(binary()) :: {:ok, String.t()} | :error

Decodes the given object ID into a string version of the UUID.

Examples

iex> decode_object_id("user_Cd4WBXFmobLLv7gfB4MuH")
{:ok, "5d446d08-df6a-404d-a1e5-decc78429b3d"}

iex> decode_object_id("something else")
:error

find_duplicate_prefixes(domains)

@spec find_duplicate_prefixes([module()]) :: %{required(String.t()) => [module()]}

Same as map_prefixes_to_resources, but returns only the entries that contain more than resource for the given prefix.

This function can be used to warn whenever duplicate prefixes are present in your modules. For example, in a test:

test "there are no duplicate object id prefixes" do
  domains = Application.fetch_env!(:my_otp_app, :ash_domains)
  assert AshObjectIds.find_duplicate_prefixes(domains) == %{}
end

find_resource_for_id(domains, id)

@spec find_resource_for_id([module()], String.t()) :: module() | nil

Same as find_resource_for_prefix/2 but accepts a (valid) object ID.

Examples

iex> find_resource_for_id(domains, "user_CWzLBdFy2f1XhrtesFferY")
MyApp.Accounts.User

iex> find_resource_for_id(domains, "florb_CWzLBdFy2f1XhrtesFferY")
nil

find_resource_for_prefix(domains, prefix)

Searches the given domains for the resource that matches the given object ID prefix.

You can get the domains through Application.get_env(:my_otp_app, :ash_domains, [])

Examples

iex> find_resource_for_prefix(domains, "user")
MyApp.Accounts.User

iex> find_resource_for_prefix(domains, "florb")
nil

map_prefixes_to_resources(domains)

@spec map_prefixes_to_resources([module()]) :: %{required(String.t()) => [module()]}

Create a map of prefixes to the resources that use that prefix.

object_id_primary_key(opts \\ [])

(macro)

Generates an object ID primary key.

This macro passes along the opts parameter to the attribute DSL.

Additionally, it accepts the following:

  • :name: The attribute name of the field. Defaults to :id.
  • :type: The name of the object ID module. Defaults to the calling module's __MODULE__.Id.