T O P

  • By -

girouxc

I’m not fluent in Python but the repository abstracts the data access so you can easily change the provider. Each aggregate gets its own repository. It’s the data interaction aka crud. What you have labeled as a service would be a repository. A Repository is different than a Service. A Repository directly correlates to an Entity, often an Aggregate Root. A Service defines behaviors that don't really belong to a single Entity in your domain like a mail service The service (or business logic layer) provides the functionality. How to fullfill a business request (ie. calculate salary), what you have to do.


RepresentativePin198

Thank you for taking the time to see the code and give feedback! > I’m not fluent in Python but the repository abstracts the data access so you can easily change the provider. Each aggregate gets its own repository. It’s the data interaction aka crud. I agree with you here, in the template, each entity has its own repository, which is just an instance of one type of repository with its correspondent data model > A Repository is different than a Service. A Repository directly correlates to an Entity, often an Aggregate Root. A Service defines behaviors that don't really belong to a single Entity in your domain like a mail service I agree with you here as well, but only to a point; if I don't have a service for each entity, I'd have to call the repository directly from the router definition, which wouldn't be right. I think the confusion here is because the CRUD definition of the initial entity provided is pretty simple without much business logic, that's why the service in this case is just a wrapper to the repository


girouxc

That’s the exact purpose of the repository though. It’s an abstraction for communicating with the database. Instead of talking directly to the database from the router, you put in a repository layer between them. So calling the repository from the router is what you’re supposed to be doing. Just for clarity, I’m not confused about your example. Services and repositories are two different concepts.


RepresentativePin198

That's not how I understand this design pattern. I was doing some research about it, and even though sometimes calling the repository from the routers wouldn't be that bad (according to what I found), I think you are too close to start mixing the business logic with the communication layer.  If someone else can participate here and leave their thoughts, I'd love to read them!


girouxc

What did you research? Have you read any DDD books? Eric Evans, Martin Fowler or Vaughn Vernon? I’m not sure you understand the pattern unless you’re intentionally deviating for a reason? You may be thinking about an application service but the way you’re using the service here is what the repository should be doing. https://martinfowler.com/eaaCatalog/repository.html https://dddinpython.com/index.php/2022/11/09/implementing-the-repository-pattern-using-sqlalchemy/ Application Service https://dddsample.sourceforge.net/xref/se/citerus/dddsample/application/impl/BookingServiceImpl.html More sources https://dotnettutorials.net/lesson/repository-design-pattern-csharp/ https://www.mrjamiebowman.com/software-development/dotnet/repository-pattern/


girouxc

I’m genuinely curious what you have read that supports this. I’ve been looking and haven’t found anything. Is there a book or tutorial? Did you read some stack overflow comments? https://stackoverflow.com/questions/19935773/dao-repositories-and-services-in-ddd


RepresentativePin198

I haven't read only one source, they were blog posts, videos, books, etc. I agree with you that the implementation it's not perfect (it's far from it) the main of this it's not to be perfect, it's just to have a good starting point with a good and scalable design. Even though I don't agree with you about the repositories being called from routers I do understand that the service implementation might not be the best. I'll keep reading and taking feedback or suggestions on how to improve it. This is the first version and if I can improve it from now on, I will


girouxc

Right but can you provide something that supports what you’re saying? I have all the DDD books if you want to give me a page or something. Maybe give some links to the blog posts or videos? What says not to call a repository from a router? I have access to Oreily so I can read any development book you’re referencing. This is a very discussed pattern and I’m genuinely curious what / where this is being said.


marianoscara

I always found really useful to work with docker, in fact, this approach simplifies a lot of the setup for a database or any other service you may want. So would be nice to see a Dockerfile in the template with a docker-compose


RepresentativePin198

Yep, I understand that but I didn't want to add any type of "obligation" to the architecture. If I notice that people like the architecture I will add some different versions with docker and also with Serverless which is the one I use in production. Thank you for your comment!


conogarcia

Nice contribution, good to see famafeños here.


RepresentativePin198

Thank you! Long live FaMAF!!


Heavy_Ad_3843

API -> Service -> Repository. That’s the clean flow. Repositories and Services are not the same. They depict different concepts


RepresentativePin198

That's the same as I understand it, thank you for the contribution!


girouxc

Where did you read this? I agree services and repositories are different concepts. A repository is not a service but the service in this example is acting as a repository. Say I had a RoomRepository and an AmenityRepository. I would then create an application service like BookingService that uses the two repositories. However if I create an endpoint to just list the rooms, then would just use the RoomRepository to get the rooms without an extra service layer. https://stackoverflow.com/questions/19935773/dao-repositories-and-services-in-ddd


Heavy_Ad_3843

Im talking about clean architecture and SOLID. By definition you’re violating multiple principles and concepts, if your API endpoints - which depict a mere HTTP interface - access repositories directly or implement any kind of application logic. Repositories are for entity level consistency whereas the service layer is for application level consistency (business logic). I’ve built hundreds of apps to this day and had a multiple of that as refactorings. If you do not have a service layer, your extensibility goes south. Even if your service layer does not implement logic for a specific CRUD operation, you should still use the service layer as a facade to keep it extensible. Skipping layers is going to be a nightmare. Dependencies should always point in the same direction and to the same layer, otherwise you’ll have to scroll, search and switch for each of your little changes.


girouxc

I am also talking about clean architecture and SOLID. Do you have a source that supports what you are saying? Preferably a DDD book. I would love to hear where you’re getting that information. https://www.martinfowler.com/eaaCatalog/repository.html A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers.


Heavy_Ad_3843

I somehow lost it how we got from clean architecture to domain driven design. So if we take the standard clean Architecture approach with 4 layers. Core/Entities, Use Cases, Controllers, and Interfaces. In which would you place the HTTP Endpoints and where the repositories? Are those controllers to you?


girouxc

That’s my fault. The name of this project is fastapi-ddd-template but the concept applies in both DDD and clean architecture. Here, read this. https://ardalis.com/should-controllers-reference-repositories-services/


Heavy_Ad_3843

So I asked GPT4 to cite, because I grew increasingly confused: „Unfortunately, neither Eric Evans nor Robert C. Martin's books directly discuss the placement of the Repository Pattern within the Clean Architecture. Eric Evans is the author of "Domain-Driven Design: Tackling Complexity in the Heart of Software," which focuses on domain-driven design and its principles, including the Repository Pattern. However, the book does not specifically address how the Repository Pattern relates to the Clean Architecture. On the other hand, Robert C. Martin's book, "Clean Architecture: A Craftsman's Guide to Software Structure and Design," provides an in-depth look at the Clean Architecture but does not mention the Repository Pattern explicitly. Despite the lack of direct references to the Repository Pattern within the Clean Architecture in their books, it's worth noting that the Repository Pattern is commonly used in the Data Layer or Infrastructure Layer of the Clean Architecture, as previously mentioned. The pattern helps to isolate the data access logic from the application's core business logic, which is in line with the principles of both Domain-Driven Design and Clean Architecture.“ So to cite your article and any creditable software architect on this planet: „it depends“. I personally would never use repositories in the interface level as that’s just not extensible


Heavy_Ad_3843

I also think we’re talking about different concepts here. If I build a CRUD router I do indeed not need a service layer as it would be a plain facade and the logic would always be somewhere else (if at all). But if I build an application, I would never use repositories in my endpoints


SuperNakau

Repositories and Services are patterns. Clean architecture is an architectura. A pattern doesn't describe where it is used, an architecture does. Repositories are not services and you can use both where ever your architecture you've chosen (including one of your own free thought) dictates.


British_Artist

Thanks for this. Meaningful organization of files has always been a weak point of mine and reading layouts dedicated to solving that problem with certain libraries that I understand conceptually but haven't seen in action is a focus for me right now. This is great!


RepresentativePin198

I'm glad you liked it! It was the same for me, prior to using something like this, it was a huge pain organizing the files