DDD & Clean Architecture: Why not define repositories in the application layer?

85 Views Asked by At

I am using Go with Clean Architecture and DDD. I don't like that I need to define my repositories in the domain layer. In the end it is the application layer that defines what it wants, e.g. as the application layer I know I want to get or save an Item, which is a domain entity, from anywhere. Why don't I define the repository interface on the spot there, in the application layer, where it is needed, instead of in the domain layer? Then the domain layer can keep itself busy with domain business rules instead of knowing that things need to be persisted, which to me seems more like an application detail.

The domain can still be responsible for creating aggregates. I would argue that it doesn't need to know about how things are persisted in order to do that. Just have the application layer pass multiple entities and/or value objects to some factory function to create aggregates; why not?

I've asked multiple LLMs but I find the answers unsatisfactory. I hope a human can shed some light and/or opinion on the issue.

3

There are 3 best solutions below

2
David Osborne On

My understanding is that the repository interfaces are defined in the domain as they are a 'tactical' DDD pattern. Also, it's possible that other domain components, domain services for example, might need to depend on a repository interface. The domain shouldn't be able to reference types in the application 'layer'.

...it doesn't need to know about how things are persisted

No, it doesn't. This is why you define the interface in the domain and the implementation elsewhere. The domain dictates the 'what' while other layers define the 'how'.

0
René Link On

Why don't I define the repository interface on the spot there, in the application layer, where it is needed, instead of in the domain layer?

I usually do that, because of the same reasons. The application layer is where the use cases, aka. interactors, reside.

Uncle Bob once showed this diagram in one of his talks you can find here.

Isolate the database

In this talk he says

"The database should plug into the business rules."

when he says this he points with his hand at the interactor. Sure because the interactor needs something from the persistence mechanism and therefore declares the interface the database can plug in.

So I would say that the repository interface belongs to the application specific business rules and therefore to the application layer.

However, there might sometimes be reasons to put the repository interface in the domain layer, the most inner circle of the clean architecture. E.g. when you separate the layer via packages in Java, you define the repositories as abstract classes and you want to use the package modifier to access package private domain entity methods. The dependency rule that all dependencies should point inward will still be satisfied. Nevertheless, I think it should be the exception to put repository interfaces in the domain layer beside the entities and I would either prefer a package by component approach. Also see this answer.

3
Yorro On

I don't like that I need to define my repositories in the domain layer

In many variations of Clean Architecture, repositories are defined in the Data Layer. By the purest definition: "Domain should not have knowledge of the persistence" and Clean Architecture supports that with the Data Layer.

"This layer [Application Layer] is kept thin. It does not contain business rules or knowledge, but only coordinates tasks and delegates work to collaborations of domain objects in the next layer down. It does not have state reflecting the business situation, but it can have state that reflects the progress of a task for the user or the program." - Eric Evans domaindrivendesign.org

But don't let us stop you from putting Persistence in the Application Layer.