Learn how to use Domain-Driven Design to build complex enterprise-level applications with Node.js & TypeScript.
Think business-logic heavy apps and organizations like Google, Microsoft and GitHub.
How do they do it?
We’ll build a Vinyl Trading Application complete with Billing, Notifications, Users & Identity Management supporting subdomains using DDD best practices.
We’ll use Node.js, Express.js, Sequelize ORM, Stripe and JWT for authentication.
How to build complex applications with Node.js and TypeScript that actually get better instead of degrading over time
How to organize your application into subdomains and separate bounded contexts
How to design rich object-oriented software implementations of the problem domain
How to discover & organize business logic using Domain Events and Event Storming
How to encapsulate business rules and validation logic in Entities and Value Objects using factories
How to use Separation of Concerns to organize your app into testable layers
Introduction to Domain-Driven Design
Getting started
Why Domain-Driven Design?
Why TypeScript?
What projects are right for Domain-Driven Design?
The main concepts of Domain-Driven Design
Layered Architecture and an isolated Domain model
TDD and Unit Testing
Model-Driven Design
What are we building?
Summary
Understanding the problem, subdomains and bounded contexts
Goals of modeling a problem domain to a solution space
Separating the solution space in subdomains
Identifying the primary domain
Supporting & generic subdomains
Bounded contexts & subdomains
Involving Domain Experts to build a Ubiquitous Language
Summary
Getting started with Domain Modeling
The goals of modeling our domain
Domain modeling building blocks
Rich vs. Anemic Domain Models
TypeScript, Express.js and Sequelize project setup
Entities
The lifecycle of an Entity
Base Entity class
Generating Entity identity strategies
Creating entities using Factory Methods
TDD approach to identifying modeling our requirements
When to write Unit Tests
Don't follow the Red-green-refactor loop to a tee
Value Objects
Difference between Entities and Value Objects
Base Value Object class
Encapsulating validation logic in Value Objects
Summary
Persistence & UI Layers
Goals of the persistence layer separation of concerns
Recap of the Onion architecture
Designing a database schema for our application
Introducing the Sequelize ORM
Hooking up ORM models and migration scripts
Entity identity generation with UUIDs instead of auto-incremented primary keys
Introducing Repositories
To use generic repositories or not
Using Repositories to perform CRUD on domain models
Using Mappers to map ORM models to Domain Models
Using Mappers to map Domain Models to ORM models
DTOs for our API layer
Using Mappers to map Domain Models to DTOs
Other patterns: Unit of Work, transactions, repo.save()
Summary
Aggregates & Domain Events
Understanding the role of Aggregates
Identifying an Aggregate
Base Aggregate class
Understanding how Domain Events allow us to co-locate domain logic
Domain Events using the Publish/subscribe pattern
Event storming to identify our domain events
Creating our first Domain Events
When to use domain services
Subscribing to Domain Events (same subdomain, same bounded context)
Subscribing to Domain Events (separate subdomain, same bounded context)
Subscribing to Domain Events (separate subdomain, separate bounded context)
Messaging Queues
Anti-corruption layers
Summary
Additional bounded contexts and onwards
Goals of the separate bounded context
Context maps and boundaries
Communication between separate bounded contexts
Application Services
To use the Use Case pattern or not
The role of the UI
Splitting bounded contexts in microservices
Packaging by module
Domain modeling improvements
DDD anti-patterns
Summary