DEV Community

Sairyss
Sairyss

Posted on • Edited on

Domain-Driven Hexagon: Guide on Domain-Driven Design, Hexagonal architecture, best practices (TypeScript and NestJS examples)

Few months ago I've created a repository to gather some architectural patterns and best practices I've been using for the last few years, both at work and for personal projects. At first It was a project for myself, but it grew and have reached a point that I can share it and hopefully more people can learn some useful practices from it.

Main emphasis of this project is to provide recommendations on how to design software applications. In this repository are presented some of the techniques, tools, best practices, architectural patterns and guidelines gathered from different sources.

Code examples are written using NodeJS, TypeScript, NestJS framework and Slonik for the database access.

Though patterns and principles presented in this repository are framework/language agnostic, so above technologies can be easily replaced with any alternative. No matter what language or framework is used, any application can benefit from principles described in this repository.

This project's architecture is mainly based on:

  • Domain-Driven Design (DDD)
  • Hexagonal (Ports and Adapters) Architecture
  • Secure by Design
  • Clean Architecture
  • Onion Architecture
  • SOLID Principles
  • Software Design Patterns

And many other sources and best practices (links to additonal resources in every section).

Check out my GitHub repository to see full tutorial with code examples:

Also, check out my other repositories:

  • Backend best practices - Best practices, tools and guidelines for backend development.
  • System Design Patterns - list of topics and resources related to distributed systems, system design, microservices, scalability and performance, etc.

Top comments (8)

Collapse
 
azer_49 profile image
wadoud

hello my freind , thank you for this great project . but when i was reading the source code of UserEntity in create methode , you used
const user = new UserEntity({ id , props })
but you haven't used the constructor function in this UserEntity class , so how it can get an object of id and props in arguments ??? i think you forget to add the constructor !

Collapse
 
mcasarrubios profile image
mcasarrubios

Thank you for sharing, it's very interesting. I would like to ask you a question. I have seen that events are emitted before you know if they have been successful. For example, in DeleteUserService, "user.delete()" shouldn't be after "this.userRepo.delete(user)":
user.delete();
const result = await this.userRepo.delete(user);
return Ok(result);

Collapse
 
sairyss profile image
Sairyss

Sorry for the late response, dev.to does not notify by email so I didn't see your comment.
Events are first only stored in memory to be emitted later, and are actually emitted after the entity is saved to the database (check out repository base class entity.publishEvents call).
If you have any other questions please create a discussion in the repository, I will get a notification and answer faster :)

Collapse
 
fiqrisr profile image
Fiqri Syah Redha

Awesome

Collapse
 
nans profile image
Nans Dumortier

Thank you for your work and for sharing this!

Collapse
 
cesce profile image
cesce

Thank you for sharing, really great job.

Collapse
 
cekingx profile image
I Dewa Gede Dirga Yasa

Thank you for the great work

Collapse
 
ovidiu_dragoi_f52588750e6 profile image
Ovidiu Dragoi

Thank you for your work. I'm using it in our projects.