How does repository depends on usecase clean architecture - clean-architecture

I understand how usecase should depend on entity, but I don't know how repository depends on usecase.
Say we want to store newly created users using userUsecase.register() to database, usecase should know about repository right? At least usecase know about the repository interface, not the implementation

Yes, the Use Case itself should only have a dependency to the repository interface and thus you should inject the repository interface into the use case. The repository interface should be defined in the application core layer (or domain layer).
The implementation of the repository interface will reside in the infrastructure layer (also referred to as persistence layer or data layer).
So that means the repository implementation does not depend on the use case. Both, the use case and repository implementation depend only on the repository interface instead. With this the Dependency Inversion principle is applied.
With that, all dependencies are pointing inwards which makes both the use cases and the repository implementation (infrastructure) dependent on the core layer. But the core (i.e. domain) layer does not have any dependencies to outer layers.

Related

Spring Beans Dependency Inyection with different configurations

I have the following doubt, probably a very basic one, that I have already managed to work out but I would like to listen if there is a different approach or actually if I am getting something wrong.
Background
I have an implementation with Springboot with a classic layered approach using Spring StereoTypes and wiring all up using Field DI (yes... I am aware it is not the best approach)
Service -> Repository -> (Something else)
In my case (something else) is a third party Rest API which I am calling using a RestTemplate with a specific configuration.The current solution has many services and repositories to deal with each of the Third Party domain entities. All of them using the same RestTemplate bean. The bean is inyected at the repository level.
Problem
So now I have been told from the Third Party System that depending on which business scenario my local services are executing, repositories need to use one of two different users, therefore, I assume that a different restTemplate config needs to be added. At first glance it drives me to move even higher the decision of which restTemplate to use. At Service level, not at the repo level. So I would need to have, lets say, a service A under a specific context whose dependencies (the repository) will need to have a specific template, and the same service A given another context, with a different dependency config.
Approach
The approach that I took is to have a configuration class where I generate different versions of the same service with different dependencies, in particular, their repositories using a specific template. Github Example
This approach seems like odd to me because up till now I have never had to do something like this ...and leaves me with the doubt if something different can be done to achive the same.
Another approach would be to inject both RestTemplates in the base repository and with an extra parameter to decide which to use in each method that it is being use at service level and repo level. Which I dislike.

DDD - Maintaining separate Domain Classes and Entity Classes in Spring Data

I'm working on a project Spring Boot project where there are two separate packages named domain and persistence.
The domain package primarily contains the Domain Classes (designed based on the business requirements) whereas the persistence package contains the repository interfaces defined by extending the repositories provided by Spring Data.
I have used Spring Data JPA annotations inside the domain classes and those classes are directly used when defining the repository interfaces as well. Everything works well here.
But the issues I have is that one could argue that domain classes do not need to know about the persistence implementation and domain classes should kept clean without polluting with Spring Data JPA annotation. This makes me this that I should maybe use a different set of classes (let's say Entity classes with more or less attributes) to implement the persistence so that I can keep the domain classes clean. But if I do this;
Spring Data repositories are going to work with these Entity Classes and I will not be able to use the interface based repositories out of the box since I will always have to map the Entity objects returned by repositories to Domain Classes.
I believe that at some point, I will introduce DTOs as well and when I reach this level, there will be too many mappings (Entity Classes to Domain Classes and then Domain Classes to DTOs). I personally think this mapping will be an overhead in the long run.
Summary -
Should I maintain Domain Model Classes and Entity Classes separately or should I just use Domain Model Classes along with Spring Data JPA annotations and KISS?
I think it is a mistake to separate the repository interfaces from the domain classes. Repositories are a part of the domain. Their implementation isn't, but you are not dealing with the implementation since that is provided by Spring Data (and JPA).
If your domain classes and your entity classes should be separate things depends on if they have different needs.
You might encounter scenarios where you need to model entity classes to accommodate the limitations of JPA or whatever persistence technology you use and you don't want to leak that into you domain.
But until you encounter that I don't see the need to separate them.
If you are concerned about annotations on your entities, it might help to realise that annotations are an extremely weak dependency. You can use your entities without the annotations even on the class path. So from a purist point of view they are a smell, but in reality I still have to find a situation where they are problematic.
If you really want to get rid of them you might want to look into jMolecules, which offer technology agnostic annotations for DDD concepts that then get translated into JPA annotations or whatever you want to use.

Is it better to use repository patterns in MVC or default MVC patterns in a Laravel?

It happens to me that I was suggested to use repository patterns in MVC for my project. I know it puts some extra security in or project but is there any other benefit of changing the project's structure to repository patterns.
Repository pattern gives an abstraction of the data layer. So that before your classes will get something from model - there is layer of repository.
Let's say that repository is agent between your controller (or other classes) and models. It is up to developer if need this kind of layer or not.
In my opinion it is good practice to use repositories. I do not want to make direct operations in models. Repository can have extra functions or overwrite some model functions. Then in your controller you send requests to repository, not to model.
When you work with Symfony Framework, you will see that they implement this Repository Pattern by default.

How to implement DDD using Spring Crud/Jpa Repository

I want to create an app by implementing DDD using Spring. Let's say I have a business entity Customer and an interface CustomerRepository.
Since spring provides CrudRepository and JpaRepository to perform basic CRUD operations and other operations like finder methods by default I want to use them. So my interface becomes
#Repository
public interface CustomerRepository extends JpaRepository<Customer, Long>{
}
But according to DDD, interfaces should be in domain layer and the implementation should be in Infrastructure layer.
Now my question is, which layer the CustomerRepository belongs to?
Short answer: although it should be any dependencies to Infrastructure in the Domain layer, for the sake of KISS, you may to do so. If you want to be a DDD purist, you define a CustomerRepository interface AND an implementation in the Infrastructure that implements both the interfaces.
Long and boring answer: In general, the Domain should not care or know about infrastructure, as in, it should not have dependencies to other layers (Infrastructure, Application, Presentation or whatever architecture you are using). Following this rule leads to a cleaner architecture.
In particular, the domain should not care about the persistence, it should behave as it runs in memory. From the Domain point's of view, the Entities mutate and that's all, no persistence is needed.
The Write side of the Domain code doesn't in fact need persistence. When the Aggregates execute commands, they are already fully loaded. And after the command is executed, the Aggregates just return the changes or the new state. The Aggregates don't persist the changes themselves. They are pure, with no observable side effects.
We, the architects, need persistence because we need to ensure that the data persist between restarts and that we can run the same code on multiple machines on the same time.
There is however, another need that the Domain code, in particular the Read and the Reactive side of the Domain (Sagas/Process managers). These components of the Domain need to query and filter the Domain Entities. The Readmodels need to return the Entities to the caller and the Sagas/Process managers need to correctly identify the right Aggregates to whom to send the Commands.
The solution is to define only the Interfaces in the Domain layer and to have implementations in the Infrastructure. In this way the Domain owns the Interface so, according to the Dependency Inversion Principle, it does not depend on the Infrastructure.
In your case, although the Domain layer depends on something from the Infrastructure part of the Spring Framework, that something is only an Interface. It is still a depency to JPA because your domain will use methods that it doesn't own but KISS could more important in this case.
The alternative would be do define an Interface that does not extend the JpaRepository with an implementation in the Infrastructure that implements this Interface and the JpaRepository Interface.
Which solution depends on you: more code duplication but less dependency or less code duplication and more dependency to JPA.

Eclipse, Spring, DDD and the repository pattern

We are developing a application using eclipse, spring, ddd and the repository pattern
Our current secenario is composed by the following plugins
Plug-in Domain.project: contains the interface Repository.class.
Plug-in Repository.project: contains the different implementations of the interface Repository.class, for instance ExampleRepositoryImpl.class. So this plug-in has Domain.project plug-in on its dependencies.
We have created Service.class, in Plug-in Domain.project, which is calling through injection, one of the implementations of Repository implemented on the Plug-in Repository.project. But the injection is not solved properly.
We are no able to add a dependecy to Repository.project from Domain.project, cause this would throw a redundancy cyclic error.
Also, since we are following the DDD approach the Domain.project could see the rest but opposite.
Thank you so much,
Kind regards,
Eclipse, Spring, DDD and the repository pattern
As you said, the repository interfaces are on the domain project.
We have create one project per every implementation of the interfaces included on the domain project.
For example, we have created a project for the implementation for the JBDCRepository, another one for the PureQueryRepository, another one for the JsonRepository, and so on.
For this reason the repository project implementations have a dependency ("see") the domain project, but the domain project doesn't have any dependency to the repository project implementations.
So, our problem takes place when we would like to choose/inject through Spring any of these repositories, since the domain project doesn't see any of the repository project implementations we get a ClassNoFoundException
Kind regards,
Brais CidrĂ¡s.
The domain shouldn't care which implementation it uses - that's why you separate repository interface from repository implementation in the first place.
In order for you to decide which implementation to use, think of how dynamic the selection of the implementation is:
Decide at server startup -> use e.g. Spring Profiles: Use a profile called "jdbc", another called "json", and so on, and activate the desired profile when starting the application. In this way, only the repository implementations of the specified profile will be instantiated and injected.
Decide at class level -> use e.g. Spring Qualifiers
If one Spring bean needs the "jdbc" implementation of your repository, whereas another one needs the "json" implementation of the same repository, then instantiate each implementation with the respective qualifier name and inject the desired repository implementation by specifying its qualifier.

Resources