Skip to content

Your First Bounded Context

Planning Your Domain

Before writing .ddd code, identify:

  1. The bounded context — what area of the business are you modeling?
  2. The commands — what actions can users take?
  3. The events — what facts are recorded?
  4. The states — what lifecycle does the aggregate go through?
  5. The invariants — what rules must hold?

Example: User Registration

Step 1: Define the Context

context Registration {

Step 2: Declare Types

type UserId = String
type Email = String
type DisplayName = String

Step 3: Define Commands

command Register {
userId: UserId
email: Email
name: DisplayName
}

Step 4: Define Events

event Registered {
userId: UserId
email: Email
name: DisplayName
}

Step 5: Build the Decider

decider User {
commands: Register
events: Registered
state: Unregistered | Active(email: Email, name: DisplayName)
initial: Unregistered
decide(Register, Unregistered) -> [Registered]
evolve(Unregistered, Registered) -> Active {
email: email
name: name
}
}
}

What the Compiler Will Check (Phase 3)

  • Exhaustiveness: Register is handled for Unregistered. Since Active is not listed in terminal:, additional decide clauses would be needed if more commands existed.
  • Evolve totality: Registered is handled for state Unregistered.
  • Type safety: All fields reference declared types.

Next Steps

  • Add validation: validate email contains "@"
  • Add more commands: ChangeEmail, Deactivate
  • Add business rules: require guards in decide clauses