Skip to main content
Welcome to ddd_cqrs_es! This library is a lightweight, high-performance Rust framework designed to help you construct highly reliable, testable, and maintainable software systems using the combined power of Domain-Driven Design (DDD), Command Query Responsibility Segregation (CQRS), and Event Sourcing (ES). The distinguishing design philosophy of this framework is that it is completely infrastructure-light. Your core domain logic—the rules that govern how your business operates—is kept entirely free of dependencies on databases, serialization formats, web frameworks, or asynchronous runtimes.

🚀 Installation

Add the crate as a dependency in your Cargo.toml:
[dependencies]
ddd_cqrs_es = "0.2.3"

Feature Flags

Our framework is highly modular. You can enable specific adapters and engines depending on your production requirements.

Enabling Durable Database Adapters:

  • SQLite Support: Enable the "sqlite" feature (uses the rusqlite driver under the hood).
  • PostgreSQL Support: Enable the "postgres" feature (uses the postgres driver under the hood).
  • MySQL Support: Enable the "mysql" feature (uses the mysql driver under the hood).
  • WASI MySQL Helper: Enable "wasi-mysql" for raw TCP MySQL query execution from generic Wasmtime/WASI runtimes.
  • Spin MySQL Helper: Enable "spin-mysql" for Spin SDK MySQL query execution.

Supported Backends:

  • SQLite / Local File: Standard local embedded SQL.
  • PostgreSQL: Stable high-performance relational database.
  • MySQL: High-performance relational database with native stores plus runtime query helpers for Wasmtime ("wasi-mysql") and Spin ("spin-mysql").
  • LibSQL / Turso: Supported for distributed edge SQL via the "wasi-libsql" query helper.
  • Redis: Supported for async event store, checkpoints, and pub/sub notifications via "redis" / "wasi-redis" / "spin-redis".

Realtime and Notification Support:

The root crate provides durable stores, checkpoints, idempotency stores, and notification primitives. HTTP streaming is application-owned.
  • PostgreSQL / SQLite / MySQL: Use durable events and checkpoints to drive polling, SSE, WebSocket, or worker pipelines in your application.
  • Redis: Provides experimental async persistence plus notification-only pub/sub wake messages. Durable replay remains the source of truth.
  • MySQL: MySQL does not provide a built-in pub/sub stream in this library; pair it with Redis, an outbox worker, binlog CDC, NATS, Kafka, or WebSocket fan-out when low-latency push notifications are required.

API Notes:

  • Aggregates are loaded by the repository using the external stream ID; the Aggregate trait does not require an id() method.
  • EventType is a serde-transparent newtype. Convert it with as_str() or into_string() when a database, UI, or protocol needs a plain string.
  • SqlSchemaConfig table-name builders validate eagerly and return Result.
  • Process managers can be coordinated by ProcessManagerRunner or AsyncProcessManagerRunner.
  • execute_idempotent(...) is portable but not crash-atomic across separate stores. Use execute_idempotent_atomic(...) with native SQL stores for production request idempotency.
FeatureDescriptionThird-Party Dependencies
defaultStandard local, thread-safe in-memory event store and memory projection runners.None
sqliteStable SQLite event store, checkpoint store, idempotency store, snapshot store, and atomic idempotent append.rusqlite
postgresStable PostgreSQL event store, checkpoint store, idempotency store, snapshot store, and atomic idempotent append.postgres
mysqlStable MySQL event store, checkpoint store, idempotency store, snapshot store, and atomic idempotent append.mysql
wasi-mysqlExperimental raw TCP MySQL query helper for generic Wasmtime/WASI runtimes.rsa, sha1, sha2, getrandom
spin-mysqlExperimental Spin SDK MySQL query helper.spin-sdk
redisExperimental async Redis event store, checkpoint store, pub/sub publisher, and command executor trait.None
wasi-redisExperimental raw RESP Redis client for generic Wasmtime/WASI runtimes.redis
spin-redisExperimental Spin SDK Redis client.spin-sdk
wasi-httpExperimental outbound HTTP helper foundation for WASI runtimes.wasip3, http, http-body-util, bytes
wasi-neonExperimental Neon HTTP SQL query helper.wasi-http
wasi-libsqlExperimental LibSQL/Turso Hrana HTTP query helper.wasi-http
wasi-postgres-tcpExperimental raw PostgreSQL TCP query helper for WASI-style runtimes.md5, base64, pbkdf2, hmac, sha2, rustls
spin-sqliteExperimental Spin SQLite host-call query helper.spin-sdk
spin-postgresExperimental Spin PostgreSQL host-call query helper.spin-sdk
wasi-supabase-rpcExperimental Supabase RPC query helper.wasi-http

⚡ Quick 10-Second Example

Here is how simple it is to initialize our write path, tie it to an in-memory event ledger, and execute a transactional command:
use ddd_cqrs_es::{InMemoryEventStore, Repository, Metadata};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. Initialize a thread-safe, local, in-memory event ledger
    let store = InMemoryEventStore::<BankAccount>::new();
    
    // 2. Bind the ledger to the repository coordinator
    let repo = Repository::new(store);
    let account_id = "account_abc123".to_owned();

    // 3. Execute a transactional command with audit tracking metadata!
    repo.execute(
        &account_id,
        BankAccountCommand::DepositMoney { amount: 100 },
        Metadata::new().with_actor_id("user_alice"),
    )?;

    // 4. Rebuild aggregate state instantly by replaying its historical facts
    let loaded = repo.load(&account_id)?;
    assert_eq!(loaded.state.balance(), 100);
    
    println!("Transaction committed! Balance is: ${}", loaded.state.balance());
    Ok(())
}

🗺️ How to Navigate This Documentation

We structured our guides as a structured, chronological path designed to take you from a complete beginner to building full-scale, distributed production applications:

Start with the CLI: ddd CLI

  • What you’ll learn: Install the ddd command, scaffold a new app with ddd init, add domain events and commands with ddd add, enable Redis/gRPC/tracing capabilities, run Spin-focused apps, and use dry-run JSON for agent/MCP workflows.

Module 1: The Patterns (Theory)

Module 2: Domain Modeling (Tutorial)

  • What you’ll learn: Build a fully validated Bank Account domain step-by-step. Implement Commands, Events (implementing DomainEvent), Errors (handling invariants), and the core Aggregate Root struct.

Module 3: Domain Tests

  • What you’ll learn: Write bulletproof business validations in microseconds. Learn why Event Sourcing is a unit-testing superpower and write elegant Given-When-Then tests using the Aggregate Test Fixture API.

Module 4: Configuring an Application

Module 5: Building an Application (Production)

Module 6: Leptos WASM SSR + Spin CQRS (Production Implementation)

  • What you’ll learn: Put everything together across focused implementation pages. Build the pure domain, Spin/WASI storage adapters, checkpointed projections, Leptos server APIs, reactive UI, runtime backend configuration, and execution playbook for a production-grade full-stack CQRS application.

Module 7: Runtimes & Cloud Deployment (Spin vs. Wasmtime)

  • What you’ll learn: Production runtimes and connection engineering. Understand the performance differences between Wasmtime CLI and Fermyon Spin connection pooling. Read our best practice architectural recommendations for database proximity, and learn how to deploy serverless WASM applications to Fermyon Cloud and SpinKube on AWS EKS, GCP GKE, and Azure AKS.
For documentation site indexing details (including where PRD and full tutorial pages are registered), see docs/docs.json.