Macro for defining type-safe, domain-specific object IDs.
ObjectIds are type-safe identifiers that combine a human-readable prefix with a value,
stored as {prefix}{separator}{id} (e.g., "user_abc-123").
Usage
defmodule MyApp.UserId do
use Trogon.Commanded.ObjectId,
object_type: "user"
end
# Create
user_id = MyApp.UserId.new("abc-123")
#=> %MyApp.UserId{id: "abc-123"}
# Convert to string
to_string(user_id)
#=> "user_abc-123"
# Parse
MyApp.UserId.parse("user_abc-123")
#=> {:ok, %MyApp.UserId{id: "abc-123"}}Type Safety
Each ObjectId type is a separate struct, providing compile-time and runtime type safety:
def process_user(%MyApp.UserId{} = id), do: ...
def process_order(%MyApp.OrderId{} = id), do: ...
process_user(MyApp.OrderId.new("123")) #=> FunctionClauseError!Proto-driven ObjectId
When using trogon_proto with trogon/object_id/v1alpha1/options.proto, you can
derive object_type and separator from proto enum value extensions:
defmodule MyApp.TicketId do
use Trogon.Commanded.ObjectId,
proto: {Acme.Type.V1.ObjectType, :OBJECT_TYPE_TICKET},
storage_format: :drop_prefix,
validate: :uuid
endThis reads object_type and separator from the proto annotation and forwards
them along with any additional options you provide.
Ecto Integration
ObjectIds implement Ecto.Type, so you can use them directly in schemas:
schema "users" do
field :id, MyApp.UserId
end
Summary
Functions
Defines a type-safe ObjectId module.
Returns true if term is an ObjectId struct; otherwise returns false.
Functions
Defines a type-safe ObjectId module.
Options
:object_type(String.t/0) - Required. The object type (e.g.,"user","order").:separator(String.t/0) - Separator between prefix and id. The default value is"_".:storage_format- Database storage format.:full- Store complete string (e.g.,"user_abc-123"):drop_prefix- Store only the id (e.g.,"abc-123") The default value is:full.
:json_format- JSON encoding format.:full- Encode complete string (e.g.,"user_abc-123"):drop_prefix- Encode only the id (e.g.,"abc-123") The default value is:full.
:validate- Validation for the raw id value (without prefix).nil- No validation (default):uuid- Validates that the id is a valid UUID:integer- Validates that the id is a valid integer string{Module, :function}- Custom validator (compile-time optimized direct call). The function receives the raw id value and returns:okor{:error, reason}. The default value isnil.
Examples
defmodule MyApp.UserId do
use Trogon.Commanded.ObjectId, object_type: "user"
end
defmodule MyApp.OrderId do
use Trogon.Commanded.ObjectId, object_type: "order", separator: "#"
end
defmodule MyApp.AccountId do
use Trogon.Commanded.ObjectId, object_type: "acct", storage_format: :drop_prefix
end
# With UUID validation
defmodule MyApp.ProductId do
use Trogon.Commanded.ObjectId, object_type: "product", validate: :uuid
end
# With integer validation
defmodule MyApp.SequenceId do
use Trogon.Commanded.ObjectId, object_type: "seq", validate: :integer
end
# With custom validator (compile-time optimized)
defmodule MyApp.CustomId do
use Trogon.Commanded.ObjectId,
object_type: "custom",
validate: {MyValidator, :check}
end
Returns true if term is an ObjectId struct; otherwise returns false.
Allowed in guard tests.
Examples
iex> is_object_id(%MyApp.UserId{id: "abc-123"})
true
iex> is_object_id(%{id: "abc-123"})
false