I understand the basic principle but I have trouble determining what is the hard line separating responsibilities of a Repository or a Service. I’m mostly thinking in terms of c# .NET in the following example but I think the design pattern is kinda universal.
Let’s say I have tables “Movie” and “Genre”. A movie might have multiple genres associated with it. I have a MovieController with the usual CRUD operations. The controller talks to a MovieService and calls the CreateMovie method for example.
The MovieService should do the basic business checks like verifying that the movie doesn’t already exist in the database before creating, if all the mandatory fields are properly filled in and create it with the given Genres associated to it. The Repository should provide access to the database to the service.
It all sounds simple so far, but I am not sure about the following:
-
which layer should be responsible for column filtering? if my Dto return object only returns 3 out of 10 Movie fields, should the mapping into the return Dto be done on the repository or service layer?
-
if I need to create a new Genre entity while creating a new movie, and I want it to all happen in a single transaction, how do I do that if I have to go through MovieRepository and GenreRepository instead of doing it in the MovieService in which i don’t have direct access to the dbcontext (and therefore can’t make a transaction)?
-
let’s say I want to filter entries specifically to the currently logged in user (every user makes his own movie and genre lists) - should I filter by user ID in the MovieService or should I implement this condition in the repository itself?
-
is the EF DbContext a repository already and maybe i shouldn’t make wrappers around it in the first place?
Any help is appreciated. I know I can get it working one way or another but I’d like to improve my understanding of modern coding practices and use these patterns properly and efficiently rather than feeling like I’m just creating arbitrary abstraction layers for no purpose.
Alternatively if you can point me to a good open source projects that’s easy to read and has examples of a complex app with these layers that are well organized, I can take a look at it too.
Additional question - I said at first that the “Service” should be doing the mandatory checks like uniqueness validation or whether the fields are filled in properly with good values, but is even that a good approach?
Instead of implementing this in every service that might create a new Movie (and it could be from different sources - import from file, different APIs, background worker, etc), wouldn’t it make more sense to add these checks to the repository itself so they always gets called?
Alternatively, do we have to handle a constraint violation in every service or could we just have the repository return a result with failure if it happens?
In short, once I start thinking in this way I start to wonder why even have a separation between repository and service.
The repository is responsible for talking to the db. Services are where your business logic lives (and ofc there’s always some leakage of logic into the db).
It’s ok for a service to call other services and multiple repositories, but a repository should only talk to the db. It should not call other repositories or anything else.
It’s ok to rely on db constraints for validation checking.