Skip to main content

Domain-Driven Design

info

Fluvius Framework is built on Domain-Driven Design (DDD) principles to help you build maintainable, scalable applications.

What is Domain-Driven Design?

Domain-Driven Design is an approach to software development that focuses on:

  • Domain Logic: Business rules and logic are the heart of the application
  • Ubiquitous Language: Code and business use the same terminology
  • Bounded Contexts: Clear boundaries between different parts of the system
  • Aggregates: Clusters of related entities treated as a single unit

Core Concepts in Fluvius

Domain

A Domain represents a bounded context in your application. Each domain encapsulates:

  • Business logic and rules
  • State management
  • Command processing
  • Event generation
from fluvius.domain import Domain

class UserDomain(Domain):
__aggregate__ = UserAggregate

class Meta:
revision = 1
tags = ["user", "identity"]

Aggregate

An Aggregate is a cluster of related entities treated as a single unit. It:

  • Enforces business invariants
  • Manages state transitions
  • Generates domain events
from fluvius.domain import Aggregate, action

class UserAggregate(Aggregate):
@action(evt_key='user-created', resources=['user'])
async def create_user(self, name: str, email: str):
# Business logic here
pass

Commands

Commands represent intentions to change state. They are:

  • Immutable
  • Validated before processing
  • Processed by aggregates
command = domain.create_command('create-user', {
'name': 'John Doe',
'email': '[email protected]'
})

Events

Events represent things that have happened. They are:

  • Immutable facts
  • Generated by aggregates
  • Stored in event log
@action(evt_key='user-created')
async def create_user(self, name: str, email: str):
# Event 'user-created' is automatically generated
pass

State Manager

The State Manager provides:

  • Read access to current state
  • Transaction management
  • Query capabilities
# Fetch current state
user = await domain.statemgr.fetch('user', user_id)

# Query state
users = await domain.statemgr.find('user', active=True)

Benefits of DDD in Fluvius

  1. Clear Boundaries: Domains provide clear boundaries between contexts
  2. Testability: Aggregates can be tested in isolation
  3. Scalability: Each domain can scale independently
  4. Maintainability: Business logic is centralized and easy to find
  5. Event Sourcing: Built-in event log for audit and replay

Best Practices

  1. Keep Aggregates Small: Focus on a single business concept
  2. Use Actions for State Changes: Always use @action decorator
  3. Validate in Aggregates: Enforce business rules in aggregate methods
  4. Use Events for Side Effects: Don't perform side effects in aggregates
  5. Keep Domains Focused: Each domain should have a clear purpose

Next Steps