0

I'm new to DDD and cutting my teeth on the following exercise. The use case is real, but my attempt to solve it with DDD is purely for learning.

We have multiple Git repos, each containing a file that we call product spec. The system needs to respond to a HTTP POST by cloning all the repos, and then update the product spec in those that match some information in the POST body. System also needs to log the POST request as the cause for updating the product spec.

I'd like to use Aggregates and event sourcing for solving this problem because they seem like a good fit. Event sourcing comes with automatic persistence of the commands, so if I convert the POST body to a command, I get auditing for free.

Problem is, the POST may match multiple product spec. I'm not sure how to deal with that. Should I create a domain service, let it find all the matching product spec and then issue an update command to each? Or should I have the aggregate root do so? If using aggregate root to update multiple entities, it itself needs to be an entity, so what would it be in my problem domain?

Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219
  • 2
    If you are trying to cut your teeth on DDD, you should probably start with an example that has a concrete domain model, rather than something that is mostly side effect coordination. – VoiceOfUnreason Aug 18 '17 at 02:05
  • @VoiceOfUnreason in other words, you don't think the use case I described is a good fit for DDD? – Abhijit Sarkar Aug 18 '17 at 02:54
  • With event-sourcing you don't get command's audit log; only events are persisted. What you are refering is command-sourcing. – Constantin Galbenu Aug 18 '17 at 06:10
  • @AbhijitSarkar not only is that kind of very technical system not a good fit for learning, but it is also not what DDD or Event Sourcing are typically good at solving. – guillaume31 Aug 18 '17 at 08:13
  • Perhaps my use case isn't the best for DDD, but how does one handle multiple entities? I can't believe that situation doesn't come up in DDD. – Abhijit Sarkar Aug 18 '17 at 15:14
  • @AbhijitSarkar I think one "bug" here is that you've mistaken event sourcing for command sourcing. I suggest you start again with a different scenario that doesn't make that mistake so that the conversation about a complex topic can be productive. – rep Aug 18 '17 at 21:15

2 Answers2

1

The first comment to your question is right (the one of @VoiceOfUnreason): this 'is mostly side effect coordination'. But I will try to answer your question: How to solve this using DDD / Event Sourcing:

  1. The first aggregate root could just be named: 'MultipleRepoOperations'. This aggregate root has only one stream of events.
  2. The command that fires the whole process could be: 'CloneAndUpdateProdSpecRepos' which carries a list of all the repos to be cloned and updated.
  3. When the aggregate root processes the command it will simply spit a bunch of events of type 'UserRequestedToCloneAndUpdateProdSpec'
  4. The second bounded context manages all the repos, and it its subscribed to all the events from 'MultipleRepoOperations' and will receive each event emitted by it. This bounded context aggregate root can be called: 'GitRepoManagement', and has a stream per repo. Eg: GitRepoManagement-Repo1, GitRepoManagement-Repo215, GitRepoManagement-20158, etc.
  5. 'GitRepoManagement' receives each event of type 'UserRequestedToCloneAndUpdateProdSpec', replays its corresponding repo stream in order to rehydrate the current state, and then tries to clone and update the product spec for the repo. When fails emits a failed event or a suceed if appropiate.
Narvalex
  • 1,824
  • 2
  • 18
  • 27
  • I think you're suggesting 2 bounded contexts, but I'm not sure what those would be. The only context that I can think of is `ProductRepoContext`. There is no other business concept involved here. `MultipleRepoOperations` and `GitRepoManagement` seems like a forced separation, the only difference being one handles collection of repos, another single. – Abhijit Sarkar Sep 01 '17 at 02:31
  • The multipleRepoOperations is a Process Manager (aka Saga) that handles requests that involves multiple entities, by dispatching commands to them and responding to failure / suceed events from those. Its responsability is to ensure that a long running transaction eventually commits a failed, succed, partial failed, etc result. It also logs all the operations that spans multiple entities, wich in this case are the repos. I did that in the past and works pretty well. – Narvalex Sep 01 '17 at 18:55
  • I upvoted you but need to create the context diagrams myself. I'll accept your answer when I've implemented this design. – Abhijit Sarkar Sep 02 '17 at 03:02
  • Thanks for the vote. I encourage you to read this page thoroughly: https://msdn.microsoft.com/en-us/library/jj591570.aspx – Narvalex Sep 02 '17 at 16:49
0

for learning purposes try to choose problem domain that has more complex rules and logic, where many actions is needed. for example small game (card game,multiplayer quiz game or whatever). or simulate some real world process like school management or some business process.