Build stuff with DDD and CQRS in an onion

F# edition
Agenda
- Example app
- Layered architecture
- Architecture we will use 🧅
- DDD + code example
- Core concepts in CQRS
- Business layer and commands + code example
- Queries
- API
What are we building?
Idea: A decentralised book library
Technologies:
- F#
- ASP.NET Core
- Framework Giraffe
Specification:
- People post books they have at home
- People can wait in queue, borrow and return books
Layered architecture



Api services, controllers
Services
- ORM
- data mapping
- data models
Dependency arrow
ISomeService
ISomeRepository
ApiService
Onion 🧅
What if the arrow pointed inwards?

Domain
Domain models
Pure logic
Database framework
SomeRepositoryImpl
Api service
Controller
Web framework
Business service
ISomeRepository
DDD Goal
- Represent domain knowledge in code
- Code is the docs
- Complex business rules are explicit
- Codebase uses words of the domain language
Goal: create a language that everyone understands
(= ubiquitous), including computer
Learn domain before 👩💻
- Talk to people (domain experts - product owner etc)!
- Focus on changes to data, not static data
- Questions to answer:
- What can happen in my domain (events)?
- How those events are produced (workflow)?
- How workflows are triggered (commands)?
What's in there?

Domain models
Behavior
Workflows
What can be done
Inform others of smth that happened
Use from outside






Code example 💻

Domain
Domain revisit
- All business knowledge is in one place
- Domain experts can understand the code
- Good for complex business rules
- Protect data integrity for writes
Command side in CQRS
Domain is only for writes, or
CQRS
- Architectural pattern
- Command and queries are different application layers
- Commands change state of the system, effectful
- Queries don't change state, free of side effects

* Command Query Responsibility Segregation
CQRS Ideas
- Different data models for read and write operations


CQRS Why?
- Queries and commands are fundamentally different
- No restrictions on queries
- Updates are protected with domain
- Optimisation techniques
- Different persistence mechanisms
- Different types of storage
- Scale read side
Separate read/write db




Business 🧅



Steps











Code example 💻

Business layer
Business revisit
- Accept commands and triggers workflows
- Glues together persistence and domain
- Defines interface for persistence layer (command side)
- Persistence is implemented somewhere else
- Performs asynchronous communication via events
Outer onion 🧅
Domain

Outer layer
Presentation (API)
- Queries - models and persistence interfaces
- API endpoints
- Composition root - glue all together
Persistence
- Implementation of command persistence
- Implementation of query persistence
Queries
- Drop domain constraints
- Own read models in the presentation
- Potential for optimisation:
- Drop ORM and use some lightweight SQL
- Different storage - document db, cache etc
- Scale by replication
Code example 💻

Presentation layer
Overview







Takeaways
- Domain centric approach
- domain knowledge in code
- protect writes
- CQRS
- Separate writes and reads
- Simpler code, performance and scalability
- Onion
-
Inner layers
- don't depend on frameworks
- define interfaces implemented outside
-
Outer layer
- depends on frameworks
- glues stuff together
-
Inner layers
THANK Y'ALL









deck
By margaretkru
deck
- 618