DeQL Overview
DeQL (Decision Query Language, pronounced “deck-el”) is a declarative language for building CQRS and Event-Sourced systems that evolve gracefully with changing business needs.
What Problem Does DeQL Solve?
Section titled “What Problem Does DeQL Solve?”Traditional CQRS/ES implementations suffer from:
- Upfront design burden: Aggregates, invariants, and event schemas must be perfectly defined before any code runs.
- Boilerplate overhead: Command handlers, event handlers, projectors, and wiring code dominate the codebase.
- Rigid evolution: Changing an aggregate or adding a new decision requires touching multiple layers.
- Opaque execution: Understanding what a system actually does when a command arrives requires tracing through multiple handlers.
DeQL addresses these by making decisions the central, inspectable, declarative unit of behavior.
Core Philosophy
Section titled “Core Philosophy”Commands represent intent.Events represent facts.Aggregates represent derived state.Decisions define how reality changes.A DeQL system is not a collection of handlers wired together. It is a set of decisions — each one a self-contained, deterministic function from (state + intent) → (new facts).
How It Works
Section titled “How It Works”Phase 1 — Define Your Domain Vocabulary
Section titled “Phase 1 — Define Your Domain Vocabulary”-- Declare what exists in your domainCREATE AGGREGATE Employee;CREATE AGGREGATE BankAccount;
CREATE COMMAND HireEmployee (employee_id UUID, name STRING, grade STRING);CREATE COMMAND PromoteEmployee (employee_id UUID, new_grade STRING);CREATE COMMAND OpenAccount (account_id UUID, initial_balance DECIMAL(12,2));CREATE COMMAND Deposit (account_id UUID, amount DECIMAL(12,2));
CREATE EVENT EmployeeHired (name STRING, grade STRING);CREATE EVENT EmployeePromoted (new_grade STRING);CREATE EVENT AccountOpened (initial_balance DECIMAL(12,2));CREATE EVENT Deposited (amount DECIMAL(12,2));Phase 2 — Assemble Decisions
Section titled “Phase 2 — Assemble Decisions”-- Simple decision: no state neededCREATE DECISION HireFOR EmployeeON COMMAND HireEmployeeEMIT AS SELECT EVENT EmployeeHired ( name := :name, grade := :grade );
-- Decision with STATE AS + WHERE guardCREATE DECISION DepositFundsFOR BankAccountON COMMAND DepositSTATE AS SELECT initial_balance AS balance FROM DeReg."BankAccount$Agg" WHERE aggregate_id = :account_idEMIT AS SELECT EVENT Deposited ( amount := :amount ) WHERE balance >= :amount;Inspect Before You Commit
Section titled “Inspect Before You Commit”-- Simulate without side effectsCREATE TABLE test_hires AS VALUES ('EMP-100', 'Charlie', 'L3'), ('EMP-101', 'Diana', 'L5');
INSPECT DECISION HireFROM test_hiresINTO simulated_hire_events;
SELECT stream_id, event_type, dataFROM simulated_hire_events;Execute Commands
Section titled “Execute Commands”-- Send commands, get events backEXECUTE HireEmployee(employee_id := 'EMP-001', name := 'Alice', grade := 'L5');EXECUTE OpenAccount(account_id := 'ACC-001', initial_balance := 1000.00);EXECUTE Deposit(account_id := 'ACC-001', amount := 500.00);
-- Query the event streamSELECT stream_id, event_type, seq, dataFROM DeReg."BankAccount$Events"ORDER BY stream_id, seq;
-- Query aggregate stateSELECT * FROM DeReg."BankAccount$Agg" WHERE aggregate_id = 'ACC-001';
-- Query a projectionSELECT * FROM DeReg."AccountBalance";Design Principles
Section titled “Design Principles”- Declarative over imperative — You describe what should happen, not how.
- Decisions are first-class — Not buried inside handler methods.
- Inspection is built-in — Every decision can be simulated without side effects.
- Progressive evolution — Start simple, refine incrementally.
- No hidden wiring — The DeReg (Decision Registry) captures the complete execution topology. Every command, decision, and event is registered and inspectable via
DESCRIBE.
Runtime Model
Section titled “Runtime Model”Relationship to Disintegrate
Section titled “Relationship to Disintegrate”DeQL is inspired by the Disintegrate approach to decision‑centric architectures. Where Disintegrate describes how to reason about decisions, state, and change over time, DeQL provides a language for expressing those ideas in a structured and executable form.