Use a custom value object or a Guid as an entity identifier in a distributed system?
Posted
by
Kazark
on Programmers
See other posts from Programmers
or by Kazark
Published on 2014-05-15T20:45:31Z
Indexed on
2014/06/11
9:40 UTC
Read the original article
Hit count: 233
tl;dr
I've been told that in domain-driven design, an identifier for an entity could be a custom value object, i.e. something other than Guid
, string
, int
, etc. Can this really be advisable in a distributed system?
Long version
I will invent an situation analogous to the one I am currently facing.
Say I have a distributed system in which a central concept is an egg. The system allows you to order eggs and see spending reports and inventory-centric data such as quantity on hand, usage, valuation and what have you. There area variety of services backing these behaviors. And say there is also another app which allows you to compose recipes that link to a particular egg type.
Now egg type is broken down by the species—ostrich, goose, duck, chicken, quail. This is fine and dandy because it means that users don't end up with ostrich eggs when they wanted quail eggs and whatnot. However, we've been getting complaints because jumbo chicken eggs are not even close to equivalent to small ones. The price is different, and they really aren't substitutable in recipes. And here we thought we were doing users a favor by not overwhelming them with too many options.
Currently each of the services (say, OrderSubmitter
, EggTypeDefiner
, SpendingReportsGenerator
, InventoryTracker
, RecipeCreator
, RecipeTracker
, or whatever) are identifying egg types with an industry-standard integer representation the species (let's call it speciesCode
). We realize we've goofed up because this change could effect every service.
There are two basic proposed solutions:
- Use a predefined identifier type like
Guid
as theeggTypeID
throughout all the services, but makeEggTypeDefiner
the only service that knows that this maps to aspeciesCode
andeggSizeCode
(and potentially to anisOrganic
flag in the future, or whatever). - Use an
EggTypeID
value object which is a combination ofspeciesCode
andeggSizeCode
in every service.
I've proposed the first solution because I'm hoping it better encapsulates the definition of what an egg type is in the EggTypeDefiner
and will be more resilient to changes, say if some people now want to differentiate eggs by whether or not they are "organic".
The second solution is being suggested by some people who understand DDD better than I do in the hopes that less enrichment and lookup will be necessary that way, with the justification that in DDD using a value object as an ID is fine. Also, they are saying that EggTypeDefiner
is not a domain and EggType
is not an entity and as such should not have a Guid
for an ID.
However, I'm not sure the second solution is viable. This "value object" is going to have to be serialized into JSON and URLs for GET requests and used with a variety of technologies (C#, JavaScript...) which breaks encapsulation and thus removes any behavior of the identifier value object (is either of the fields optional? etc.) Is this a case where we want to avoid something that would normally be fine in DDD because we are trying to do DDD in a distributed fashion?
Summary
Can it be a good idea to use a custom value object as an identifier in a distributed system (solution #2)?
© Programmers or respective owner