-2

I'm new to DDD and I would like to clarify some concepts. I'm thinking about DDD in the client-side.

The first one is regarding transactions: My understanding is that transactions are a responsibility of the application layer, when the use case has to coordinate different entities with some level of integrity. However, what if we have an aggregate. Is that ok to have the transaction in the repository of that aggregate?

A second question regarding transactions would be: suppose the user/client doesn't have permission to access some of the collections which should be part of a transaction. Then, instead of calling a repository or coordinating the transaction in an application service, I suppose we should just call a service which would communicate to the server a request, which in turn would create the necessary transaction. Is that correct? If so, this service would be an application, domain or infrastructure service?

Btw, if it helps: I'm using Angular and Firestore/Cloud Functions. And I'm trying to do "functional" DDD (with anemic models).

2
  • Just to clarify: a lot of people seem to have this notion of "if I have a client that needs some service to do something for it, is it an application, domain, or infrastructure service?" It doesn't work that way. The word service has different meaning in "client that needs a service" (the "service" here refers to a high level business capability) compared to its meaning in the context of talking about internal layering of a DDD app (there, it just means: some object or function I can call that isn't really an aggregate or a value or whatever else). 1/2 Jun 17 at 21:09
  • Clients don't call your infrastructure services. Infrastructure code just implements generic capabilities; it's domain and application services that drive (orchestrate and make use of) your infrastructure services, because domain and application services are the ones that implement the high level policies. A client makes a request to an application service, which in turn creates whatever domain objects it needs and calls whatever domain services it needs to fulfill its use case. These will, at certain points of their execution, make calls to infrastructure code to actually do something 2/2 Jun 17 at 21:09

2 Answers 2

0

The first one is regarding transactions: My understanding is that transactions are a responsibility of the application layer,

That's my understanding as well. Certainly not something to do in the link layer. ; )

when the use case has to coordinate different entities with some level of integrity. However, what if we have an aggregate. Is that ok to have the transaction in the repository of that aggregate?

Sure. As long as changes to the aggregate are made atomically. No changing your mind halfway without cleaning up after yourself (which is called a rollback).

A second question regarding transactions would be: suppose the user/client doesn't have permission to access some of the collections which should be part of a transaction. Then, instead of calling a repository or coordinating the transaction in an application service, I suppose we should just call a service which would communicate to the server a request, which in turn would create the necessary transaction. Is that correct? If so, this service would be an application, domain or infrastructure service?

Huh? Um I guess? Not sure why you're mixing security and transaction issues together. Transactions don't care what interrupts them. Just that they were interrupted.

1
  • So, complementing my question, the use case is: a manager recevies an invitation from an employee, to enter the organization. On accepting the invitation, 3 firestore colellections should be changed in a transaction (not an aggregate): Employee{ companyId }, Company{ EmployeeId } and Connection{ EmployeeId, CompanyId }. I could use serverless commits directly to the Firestore - if the Manager had write privilegies in the Emplyoee collection, which he doesn't. Jun 18 at 22:59
0

An aggregate is supposed to ensure the invariants of a group of related entities and value objects. It seems therefore perfectly ok to have transactions in the repository when persisting the aggregate.

For example, imagine that you have an aggregate made of a Team and team Memberships, with invariant constraints on the size of the team. Now you add a couple of memberships to the team. If you want to persist the team, it is important that either all the changes are persisted, or that the operation fails and none of the update is performed. You'd need a transaction for that.

But your second question needs some more thoughts: if the user/client doesn't have permission to access some collections involved in the transactions, then you should prevent this user to change your aggregate in the first run. Not because of the authorizations, but to prevent the user to try changes that are doomed to fail. This situation doesn't appear in my example: a user who can manage the Team can manage the related Memberships; but such user is not necessarily entitled to modify the Member identity, which are in a separate aggregate.

Usually, user management is not part of the domain logic. This authorization control would therefore be part of the application services. This being said, authorization control with finer granularity than aggregates is usually a warning that the granularity of the aggregate might have to be considered.

2
  • So, complementing my question, the use case is: a manager recevies an invitation from an employee, to enter the organization. On accepting the invitation, 3 firestore colellections should be changed in a transaction (not an aggregate): Employee{ companyId }, Company{ EmployeeId } and Connection{ EmployeeId, CompanyId }. I could use serverless commits directly to the Firestore - if the Manager had write privilegies in the Emplyoee collection, which he doesn't. Jun 18 at 22:39
  • If they are not in the same aggregate, the change will have to be processed by each aggregate for its part. Domain events make the glue, and the saga pattern can help to get the things either done, or revert if things go wrong (e.g. a failing authorisation control).
    – Christophe
    Jun 19 at 0:16

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.