Why DDD with Ironflow
Ironflow’s core primitives — entity streams, projections, sagas, and event-driven functions — map directly to the tactical patterns of Domain-Driven Design. If you already practice DDD, this section shows you exactly how Ironflow implements each pattern. If you’re new to DDD, you’ll find collapsible concept definitions alongside every mapping.
Primitive-to-Pattern Mapping
Section titled “Primitive-to-Pattern Mapping”| Ironflow Primitive | DDD Pattern | Page |
|---|---|---|
| Entity Streams | Aggregate Roots | Aggregates & Entity Streams |
appendToStream() events | Domain Events (persisted) | Commands, Events & Reactions |
| Projections | Read Models (CQRS) | CQRS with Projections |
| Sagas | Distributed Sagas | Sagas & Process Managers |
emit() / event triggers | Commands & Domain Events | Commands, Events & Reactions |
publish() / subscriptions | Integration Events | Commands, Events & Reactions |
Strategic DDD with Ironflow
Section titled “Strategic DDD with Ironflow”While Ironflow’s strongest alignment is with tactical DDD patterns, its architecture naturally supports strategic concepts too.
Bounded Contexts
Section titled “Bounded Contexts”A bounded context defines a boundary within which a particular domain model applies. In Ironflow, bounded contexts emerge naturally from:
- Function scoping — each function subscribes to specific event types, creating natural context boundaries. An
order-processingfunction only reacts toorder.*events. - Entity stream namespacing — entity types like
order,customer, andinventoryeach define their own event vocabulary and consistency boundary. - Environments — Ironflow’s multi-environment support can model separate deployment contexts (e.g.,
payments-servicevsshipping-service).
Ubiquitous Language
Section titled “Ubiquitous Language”DDD emphasizes using consistent domain terminology across code and conversation. Ironflow’s event-driven model reinforces this:
- Name events in past tense using domain language:
order.placed,payment.captured,shipment.dispatched— notorder_table_insertorhandle_order_v2. - Name entity streams after domain concepts:
order-123,customer-456— notrow_42orentity_abc. - Name functions after business processes:
process-order,fulfill-shipment— nothandler-1orbackground-job.
Context Integration
Section titled “Context Integration”Bounded contexts need to communicate. Ironflow provides two integration mechanisms:
emit()— publishes events that trigger workflows within a context. These are domain events: internal, rich, and tightly coupled to the context’s model.publish()— publishes events to topics for cross-context communication. These are integration events: leaner, designed for external consumers, and decoupled from internal models.
This distinction maps directly to the DDD concept of domain events vs integration events. Keep domain events rich and context-specific; keep integration events slim and stable.
Anti-Corruption Layer (ACL)
Section titled “Anti-Corruption Layer (ACL)”When integrating with external systems or bounded contexts that have different models, use an Anti-Corruption Layer to translate between schemas. In Ironflow, this is a function that:
- Subscribes to integration events from the external context
- Transforms the event schema to your domain model
- Emits domain events in your context
// ACL: Translate legacy "OrderCreated" to our domain's "order.placed"export const legacyOrderACL = ironflow.createFunction( { id: "legacy-order-acl", triggers: [{ event: "legacy.orders" }], // External system events }, async ({ event, step }) => { // Transform legacy schema → domain schema await step.run("translate-and-emit", async () => { await ironflow.emit("order.placed", { orderId: event.data.order_id, // snake_case → camelCase customerId: event.data.customer_ref, items: event.data.line_items.map((li: any) => ({ sku: li.product_code, qty: li.quantity, price: li.unit_price, })), total: event.data.order_total, }); }); },);The ACL protects your domain model from external schema changes. When the legacy system changes, you update the ACL — not your core domain logic.
Published Language
Section titled “Published Language”For integration events shared across contexts, define a Published Language — a stable, versioned schema contract. In Ironflow:
- Use topics with explicit versioning:
notifications.order.v1,analytics.revenue.v2 - Document the schema in a shared location (e.g., a schema registry or API spec)
- Version integration events independently from domain events
- Use upcasters for backward compatibility when evolving schemas
Reading Guide
Section titled “Reading Guide”New to DDD? Read these pages in order — each builds on the previous:
- Aggregates & Entity Streams
- Commands, Events & Reactions
- CQRS with Projections
- Sagas & Process Managers
- Putting It All Together
Experienced with DDD? Jump directly to the pattern you need from the mapping table above.