I am aware that in some situations such statements don't present reality, which is why I included the Twitter example (their API and internals have a numeric ID next to the username/handle. Users can change the handle). But in many domains there are clear constraints on those identifiers. And sometimes the domain is limited by some RFC,standard or external API, that has a clear concept for the ID already, in case of the last example.
Currently, event_sourcery enforces use of UUIDs.
One can "encode" (hash) the domain ID into a UUID with UUIDv5. That works one-way, since it is a Hash. E.g. aggregate_id = UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, "https://envato.com").
It will allow lookups without some intermediate mapping projection: e.g. repo.load(Aggregates::Website, UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, params[:url])). Which is usefull.
But it does not hold the original value (it is a one-way hash). In the URL example, we still need to store the the original URL if we want repo.load(Aggregates::Website, url_uuid).base_url to work, for example.
It also does not free up the ID for aggregates that want or need to have a meaningful ID. In my "Actor" example, actor.id should really return the actual URI and not the UUID. I'm currently working around this by having separate value objects for my domain. E.g. Aggregates::Actor::AsActivityPubActor#id returns the Aggregates::Actor#uri instead. But this is confusing and requires extra moving parts and layers (such as those value objects, or decorators, etc)
Is there a particular reason why the limitation to enforce UUIDs as aggregate_ids is there? And if not, would a PR be welcome in which I remove that limitation in both event_sourcery and event_sourcery-postgres?
I would like my Aggregate Roots to be able to have a meaningful ID.
Some examples:
username
.I am aware that in some situations such statements don't present reality, which is why I included the Twitter example (their API and internals have a numeric ID next to the username/handle. Users can change the handle). But in many domains there are clear constraints on those identifiers. And sometimes the domain is limited by some RFC,standard or external API, that has a clear concept for the ID already, in case of the last example.
Currently, event_sourcery enforces use of UUIDs.
One can "encode" (hash) the domain ID into a UUID with UUIDv5. That works one-way, since it is a Hash. E.g.
aggregate_id = UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, "https://envato.com")
.It will allow lookups without some intermediate mapping projection: e.g.
repo.load(Aggregates::Website, UUIDTools::UUID.sha1_create(UUIDTools::UUID_URL_NAMESPACE, params[:url]))
. Which is usefull.But it does not hold the original value (it is a one-way hash). In the URL example, we still need to store the the original URL if we want
repo.load(Aggregates::Website, url_uuid).base_url
to work, for example.It also does not free up the ID for aggregates that want or need to have a meaningful ID. In my "Actor" example,
actor.id
should really return the actual URI and not the UUID. I'm currently working around this by having separate value objects for my domain. E.g.Aggregates::Actor::AsActivityPubActor#id
returns theAggregates::Actor#uri
instead. But this is confusing and requires extra moving parts and layers (such as those value objects, or decorators, etc)Is there a particular reason why the limitation to enforce UUIDs as aggregate_ids is there? And if not, would a PR be welcome in which I remove that limitation in both event_sourcery and event_sourcery-postgres?