1

Some user actions quite naturally lead to find-or-create situations. For example, user logs into a system by alternative method and find-or-create is called give email. Or, another example, User is created given Buyer's email. But of course, if there already is a user, that action causes find-or-create. Some databases (think of them as foundations for DDD's repositories) even have upsert functionality for these cases.

On the other hand, I feel that find-or-create is not truly business domain action. Of course, there is a system invariant to be preserved here (for one of the examples above - "each buyer should have a user, identified by email").

There may be also other behavior in between "if does not exist, create; then return existing". For example, logging: are we to log creating separately? Undo: just "find" does not contain anything to undo, unlike "create"; there may be other aspects as well, which come into play in "create" part or only in "find" part, or both.

Given this, how find-or-create should be understood in DDD (domain-driven design)? Is it low-level operation or part of domain logic?

I am aware of debates on how much business logic should live in database for the sake of integrity, this question is not about that. In any practical implementations actions are broken into sub-actions (for instance, as a transaction script). The question is whether find-or-create is usually part of the business or the underlying data access layer? Or maybe this is an example of a very simple service?

  • Upserts are part of your data access layer, but that seems obvious from your question. However, "each buyer should have a user identified by email" is a business rule. – Robert Harvey May 26 '18 at 18:09
  • Rule is clearly domain. When invariant is maintained by "find-or-create" procedure - is it still business logic? That transition from business to data is elusive. Where belongs the procedural logic like "if does not yet exist, create one, otherwise return existing"? NB, there may be other aspects at play there. For example, logging, checking permissions, undo logic, ... – Roman Susi May 26 '18 at 19:21
  • I guess I'm just wondering why this matters. Is the precise vocabulary really all that important? – Robert Harvey May 26 '18 at 20:51
  • In my experience, precise vocabulary usually matters. It allows to make less modeling mistakes early. – Roman Susi May 27 '18 at 8:50
  • A tough position to take, when so much of our technical vocabulary is either ambiguous, market-speak, or a crutch for not knowing what you are doing. – Robert Harvey May 27 '18 at 20:37
2

Given this, how find-or-create should be understood in DDD (domain-driven design)? Is it low-level operation or part of domain logic?

In key domains (in the places where we are doing because that's where we derive competitive advantage), I think it wants to be part of the domain logic.

Which is to say, the interface of the repository should be understood to have the semantics of

Identifier -> Maybe<Aggregate>

We often describe behaviors as though time is absolute and messaging is reliable. But that abstraction doesn't hold up particularly well in the real world, and certainly not in the distributed digital world. If the abstraction doesn't really hold up, then I'd prefer to be explicit about the fact that it doesn't.

Personally, I get a little twitchy at the idea that magic things happen when the domain model and the database disagree about the state of the world.

  • All true. But what does any of this have to do with upserts? – Robert Harvey May 27 '18 at 20:38
  • If I could go over the answer with a marker, I would highlight: "it wants to be part of the domain logic" and "If the abstraction doesn't really hold up, then I'd prefer to be explicit about the fact that it doesn't." Enough guides to resolve find place for upserts. – Roman Susi May 28 '18 at 3:14
1

I am under the impression you are overthinking this. Code which implements business logic is in in all layers of your system. Sure DDD advocates the core logic should be in the "domain layer", nevertheless most software engineers don't hesitate to implement certain features directly in the database (like constraints, unique indexes, views with specific queries, and sometimes also stored procedures). Moreover, there is always UI logic in the UI, reporting logic in the reports, all of them caused by business requirements.

So if your data access layer provides something like an "upsert" as a basic operation, and you have some business requirements where it can be used in a sensible manner, then use it - sure it is an implementation of business logic, but not more or less justified than the other cases I mentioned where you find BL outside the domain layer.

  • I understand this answer as well as comments to my question as urging to apply KISS principle, well... I just probably will need to accept that unless something more definite comes in a few days. Thanks! – Roman Susi May 27 '18 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.