Usage example
Uuid Value Object
A strongly-typed, immutable UUID wrapper.
Prevents primitive obsession and ensures valid IDs.
import { Uuid } from '@nestjstools/domain-driven-starter';
const id = Uuid.generate();
const fromString = Uuid.fromString('f47ac10b-58cc-4372-a567-0e02b2c3d479');
console.log(id.toString());Why use Uuid as a Value Object?
Instead of:
const id: string = '...';You get:
Validation
Explicit domain meaning
Type safety
Immutable identity
Supports:
UUID v7 (recommended)
UUID v4 (compatible)
2️⃣ DomainEvent Interface
Minimal interface for domain events.
You define your own events:
Why Domain Events?
They allow:
Decoupled side effects
Clear domain traceability
Event-driven architecture
Integration with messaging systems
Auditability
3️⃣ AggregateRoot<T extends DomainEvent>
The central building block of your domain model.
Provides:
Identity handling
Event recording
Controlled creation
Event extraction
Constructor Pattern
The constructor is protected, meaning:
Only subclasses can instantiate it
Prevents uncontrolled aggregate creation
Encourages static factory methods
In your aggregate, you usually make the constructor private and expose a createNew() method.
Methods
recordEvent(event: T): void
Records a domain event internally.
Used inside aggregate methods when something meaningful changes.
popRecordedEvents(): T[]
Returns recorded events and clears the internal list.
Used after persisting the aggregate to publish events externally.
🧩 Example: Order Aggregate
🔁 Typical Usage Flow
Create aggregate via static factory.
Aggregate records domain events.
Repository saves aggregate.
Application layer calls
popRecordedEvents().Events are published to an event bus (e.g. messaging library).
This keeps:
Domain pure
Infrastructure separate
Side effects decoupled
🏗 Where This Library Fits
Perfect for:
DDD projects
CQRS systems
Event-driven architecture
Clean architecture
Microservices
Monoliths with strong domain boundaries
Works with:
NestJS
Express
Fastify
Standalone Node.js
Any framework
🧪 Testing
Because it is framework-agnostic:
No DI required
No mocking frameworks needed
Pure unit tests
Aggregates are deterministic
Example:
Last updated
Was this helpful?