I'm learning DDD and I have a question.
Suppose there is a Graph entity with associated Node and Edge entities, corresponding to the vertices and edges of the graph. A node represents some business domain process, and an edge represents the interaction between processes. There are some business logic rules. For example "Nodes has unique names in graph". And there are 2 types of operations in the application:
- Node and edge creation using REST API (for example POST /nodes/ and POST /edges/).
- Import Graph data with all nested entities.
Logically, Graph is the root aggregate, and Node and Edge should be created and modified using it. But then 2 questions arise:
- To implement a REST API, do I really need to read all nested graph edges (there could be about 10,000 of them) from the DB in order to create or update just 1 object and check the necessary business logic invariants?
- Suppose, after all, there is some kind of EdgeCreateService service created within the REST API, which performs business logic checks and creates a new record. Then, when implementing Graph import operation, you will have to process all records through this service in order to perform business logic checks and not break DRY.
It's possible to create EdgeCreateService which accepts an IRepository interface containing the necessary methods to perform business logic checks. For example, IRepository.get_nodes_by_name(...)
to check the uniqueness of nodes names inside EdgeCreateService. And 2 implementations of this interface: DBRepository (for REST API) and InMemoryRepository (for import). But in this case, it turns out that the work is not done using the root aggregate. And this contradicts DDD.
Can someone tell what is the right thing to do in this case?