Nest with DDD

fvdavid
3 min readJun 14, 2020

Domain-Driven Design and DDD + Nest

The picture above is The Golden Compass.
I like to make a little perception of DDD to the Golden Compass. Because both of them, show the direction.

From Wikipedia “Domain-driven design (DDD) is the concept that the structure and language of your code (class names, class methods, class variables) should match the business domain.”
A business domain in object-oriented programming is the set of classes that represent objects in the business model being implemented.

Introduced by Eric Evans in his book, Domain-Driven Design: Tackling Complexity in the Heart of Software.
DDD is the expansion upon and application of the domain concept, as it applies to the development of software.
It aims to ease the creation of complex applications by connecting the related pieces of the software into an ever-evolving model.

DDD’s strategic design goes on to describe a variety of ways that you have relationships between Bounded Contexts. It’s usually worthwhile to depict these using a context map.

In a large system without any overarching principle that allows elements to be interpreted in terms of their role in patterns that span the whole design, developers cannot see the forest for the trees.
We need to be able to understand the role of an individual part in the whole without delving into details of the whole.
A ” large-scale structure” is a language that lets you discuss and understand the system in broad strokes.
A set of high-level concepts and/or rules establishes a pattern of design for an entire system.
This organizing principle can guide design as well as aid understanding. It helps coordinate independent work because there is a shared concept of the big picture of the role of parts and the shape of the whole.

Nest + DDD

I trying to implement a Domain-Driven Design.
Starting from my domain logic, I might want to implement it in a class like the following:

export class UserDomain { 
@IsString() readonly fullName: string;
@IsString() readonly password: string; @IsEmail() readonly email: string;
}

And this for entity

@Entity()
export class User {
@PrimaryGeneratedColumn('uuid')
userId: string;

@Column({ length: 100 })
fullName: string;
@Column({ length: 100 })
email: string;
@Column()
password: string;
}

Here I need to get access to the userRepository to create a new user, but following the principles of the clean architecture:

export interface ICreateUserService {
create(userDomain: UserDomain): Promise<UserDomain>;
}

Inject the dependency in the userEntity.
Then I create a simple in-memory implementation:

@Injectable()export class CreateUserService implements ICreateUserService {
constructor(
@InjectRepository(User) private usersRepository: Repository<User>
) {}
async create(user: UserDomain): Promise<UserDomain> {
return this.usersRepository.save(user);
}
}

And controller looks like:

@Controller('users')
export class UsersController {
constructor(
@Inject(TYPES.applications.ICreateUserApplication) private createUserApp: ICreateUserApplication) { }
@UsePipes(new ValidationPipe())
@Post('/create')
async create(@Res() res, @Body() userDomain: UserDomain) {
const stock = await this.createUserApp.create(userDomain);
return res.status(HttpStatus.OK).json(stock);
}
}

Don’t forget to wire everything together by using a module:

const createUserApp = { 
provide: TYPES.applications.ICreateUserApplication,
useClass: CreateUserApplication
};
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [createUserApp],
})
export class UsersModule {}

So, that’s all the basic step, and you ready to rock by now.
That’s NestJs, clean architecture/DDD, and Typescript as well.
For full code, check and look at my Github.
Thanks, fellas.

--

--