DDD (Domain Driven Design) with the Moleculer #956
-
Hi, does anyone have idea how to organize Moleculer project with DDD (Domain Driven Design)? Including API Gateway (moleculer-web). Hard to understand differences between controllers and Moleculer's actions and methods. Maybe some GitHub examples? Can't find any. :( |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
First of all I want to say that this is very subjective and depends on many factors including the product team size, product scope, etc. I like to think of DDD as a set of guidelines rather than strict rules. Ultimately, this is about code organization and encapsulation/separation of concerns. Like adhering to SOLID principals in OOP, you will likely never perfectly align your code but attempting to "should" help with code organization and collaborative efforts. There are two sides to DDD: Strategic DDD focuses on organizing your software systems into domains, sub-domains, and bounded contexts by collecting information from subject matter experts in the domain you are modeling. Tactical DDD focuses on organizing the code into modules that align with the context map created during strategic DDD and which separates concerns into different layers such that the problem domain can be the focus on a single layer of any one module in your system. There are of course different types of layering approaches when engineering software but tactical DDD focuses more on the modeling of the domain itself with a focus on organizing your domain entities into objects/classes that aggregate the concepts for a single entity and strongly define types, interfaces, subordinate entities, and value objects which make up the domain. Additionally there is a focus on the abstraction of entity repositories and abstract domain services which would be required dependencies for your application. Many product teams (from what I've gathered from various sources online and what is practiced by my team) tend to lean towards an onion or hexagonal architecture type pattern for the layering of these modules when embracing tactical DDD. This approach differs from MVC (model view controllers architectures) and defines the domain, application, and infrastructure layers with the domain at the core wrapped by an application which provides services supporting the domain and an infrastructure layer which implements ports (for each entity within the domain) and adapters (technology specific implementations for the port). The infrastructure implementations are often provided to the application using dependency injection. As with any type of software layering, the use of interfaces for cross-layer dependencies to limit bleeding implementation specific information between layers is the ultimate goal here. The infrastructure layer in this architecture is the outmost concentric hexagon and is the layer by which all external integrations take place. This includes your API/gateway, integrations with external dependencies for example, SaaS providers, and communication ports such as messaging, REST, and email, etc. I suggest reading more about this architectural pattern here: https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/ I think the author does a great job explaining this and I personally love the diagrams. So, with the architectural stage set, let's talk about Moleculer in particular. Since Moleculer is a microservice framework we could say that it focuses on decomposition of a problem domain into compartmentalized units called "services". On my team we often create a direction relationship between microservices (implemented in our infrastructure layer) with application services (those services which wrap the domain layer and are implemented in the application layer). As I said earlier, how you organize these codebases depends a lot on various details. For my team, we are small enough that it doesn't make sense to have a separate codebase for each microservice. In some organizations/teams this is ideal for agility but this is less about project organization and more about operational organization and is very closely aligns to DevOps practices. For our small team, collocating multiple microservices in a single package with its own CI/CD pipeline works great. That being said, we organize our codebases (a single repo) to align with a domain/sub-domain within our system (rather than say, a bounded context or standalone microservice). As our team grows we may find the need to break these codebases up into smaller modules for each bounded context but even then there will likely still be multiple microservices in a single module. I would suggest taking a look at the following codebases. While they are not written in JavaScript/Typescript, are more OOP and less functional in nature, I do think they may help provide some clarity around ways to approach DDD, both strategically and tactically:
That being said, there is nothing like hands-on experience for this sort of thing. These concepts didn't really click for me until I attempted to practice implementing these patterns in a project of my own. Even then, I still think I'm learning and gaining new perspectives daily. I hope this helps provides some clarity! Please feel free to ask any questions and I will try to follow-up as I find time. |
Beta Was this translation helpful? Give feedback.
First of all I want to say that this is very subjective and depends on many factors including the product team size, product scope, etc. I like to think of DDD as a set of guidelines rather than strict rules. Ultimately, this is about code organization and encapsulation/separation of concerns. Like adhering to SOLID principals in OOP, you will likely never perfectly align your code but attempting to "should" help with code organization and collaborative efforts.
There are two sides to DDD: Strategic DDD focuses on organizing your software systems into domains, sub-domains, and bounded contexts by collecting information from subject matter experts in the domain you are modeling. Tactical D…