In this post, I want to share my approach to developing the domain layer, applying the principles I've learned from the book "Clean Architecture" by Robert C. Martin, as well as some concepts extracted from "Domain-Driven Design Distilled" by Vaughn Vernon.
Clean Architecture | Domain-Driven Design Distilled |
---|---|
For this layer, I've used my small boilerplate, which you can check out at the following link: https://dev.to/julianlasso/typescript-boilerplate-l9c
What's all this about?
My current project involves developing a To-Do application with user authentication. Despite being a seemingly straightforward task, it has become a valuable opportunity to apply the knowledge I've gained about clean architecture and the application of some concepts of what is Domain-Driven Design (DDD).
The project has been organized into three main layers: Domain, Application, and Infrastructure, and possibly the Presentation layer in the future.
Domain Layer
In the domain layer, I've focused on four key aspects:
Value Objects: They represent immutable and fundamental concepts in the application's domain.
Entities: These are objects that have a unique identity and can change over time.
Commands and Their Validators: Handling the actions that can be performed in the domain and their associated validation rules.
Aggregates: Structures that encapsulate multiple value objects and entities.
I've also considered the design of interfaces for future repositories and the handling of domain layer-specific exceptions. However, I'm evaluating whether information related to repository interfaces and commands along with their validators should be placed in the application layer. Time and experience will guide me in this decision.
You can find the repository for the domain layer at the following link, where I've achieved 100% unit test coverage:
https://github.com/ProfeJulianLasso/todo-backend-domain
Structure
The following is the current structure of the domain layer.
📦src
┣ 📂aggregates
┃ ┣ 📂base
┃ ┃ ┣ 📜aggregate.base.ts
┃ ┃ ┗ 📜index.ts
┃ ┣ 📜index.ts
┃ ┣ 📜security.aggregate.ts
┃ ┗ 📜to-do.aggregate.ts
┣ 📂common
┃ ┣ 📂enums
┃ ┃ ┗ 📜.gitkeep
┃ ┣ 📂exceptions
┃ ┃ ┣ 📜domain.exception.ts
┃ ┃ ┗ 📜index.ts
┃ ┣ 📂interfaces
┃ ┃ ┣ 📜complete-to-do.interface.ts
┃ ┃ ┣ 📜create-to-do.interface.ts
┃ ┃ ┣ 📜create-user.interface.ts
┃ ┃ ┣ 📜index.ts
┃ ┃ ┣ 📜to-do.interface.ts
┃ ┃ ┣ 📜user.interface.ts
┃ ┃ ┗ 📜value-object-exception.interface.ts
┃ ┗ 📜index.ts
┣ 📂entities
┃ ┣ 📜index.ts
┃ ┣ 📜to-do.entity.ts
┃ ┗ 📜user.entity.ts
┣ 📂services
┃ ┗ 📜.gitkeep
┣ 📂value-objects
┃ ┣ 📂base
┃ ┃ ┣ 📜boolean-value-object.base.ts
┃ ┃ ┣ 📜config-value-object.base.ts
┃ ┃ ┣ 📜id-value-object.base.ts
┃ ┃ ┣ 📜index.ts
┃ ┃ ┣ 📜string-value-object.base.ts
┃ ┃ ┗ 📜value-object.base.ts
┃ ┣ 📜completed.value-object.ts
┃ ┣ 📜index.ts
┃ ┣ 📜status.value-object.ts
┃ ┣ 📜to-do-description.value-object.ts
┃ ┣ 📜to-do-id.value-object.ts
┃ ┣ 📜to-do-title.value-object.ts
┃ ┣ 📜user-email.value-object.ts
┃ ┣ 📜user-id.value-object.ts
┃ ┣ 📜user-name.value-object.ts
┃ ┗ 📜user-password.value-object.ts
┗ 📜index.ts
Diagrams
If for some reason you do not wish to review the code, here are the modeling diagrams of the most relevant sections.
Aggregates
Entities
Value Objects
Final words
I appreciate any questions, doubts, concerns, or contributions you may want to make.
I'm completely open to receiving any type of feedback. Please don't hesitate to contact me; I'll be delighted to receive your comments.
Update September 23, 2023
Commands and their validations are passed to the application layer.
Top comments (3)
Hi, what application did you use for the diagrams?
Hi, I apologize for the very late reply. I used JetBrains IntelliJ IDEA - jetbrains.com/idea/
Thanks for the article, comrade. What would be your take on relationship between feature (as in Redux) and domain?