Skip to content

Include

Includes allow you to split a RIDDL model across multiple files, inserting content from one file into another. This is essential for organizing large models and enabling team collaboration.

Purpose

Includes help you:

  • Organize large models: Split domains, contexts, or entities into separate files
  • Enable parallel work: Team members can edit different files simultaneously
  • Improve readability: Keep individual files focused and manageable
  • Reuse definitions: Share common types or patterns across contexts

Syntax

include "path/to/file.riddl"

The path is relative to the file containing the include statement.

An Include Is a Node, Not a Paste

It is tempting to think of an include as textual substitution. It is not. The include becomes a node in the model, and the definitions from the included file are that node's children.

Nothing is copied. Traversal descends through the node, so the included definitions participate exactly as though they had been written in place — references to them resolve, validation covers them, and generators see them.

The node also records the file the content came from, which is how a diagnostic can point at the right file and line.

Flattening discards that origin

riddlc flatten removes include nodes, promoting their children into the enclosing container. The definitions survive; the record of which file each came from does not.

A model does not need flattening to work — it already works. Flatten only when a single self-contained file is genuinely what you want, and expect to lose the file structure in exchange.

Example: Organizing a Domain

A complex domain might be organized like this:

main.riddl

domain ECommerce is {
  include "types/common-types.riddl"
  include "contexts/catalog.riddl"
  include "contexts/orders.riddl"
  include "contexts/payments.riddl"
  include "epics/checkout-flow.riddl"
}

types/common-types.riddl

type Money is { amount: Decimal, currency: CurrencyCode }
type CurrencyCode is any of { USD, EUR, GBP, JPY }
type Address is {
  street: String,
  city: String,
  country: String,
  postalCode: String
}

contexts/catalog.riddl

context Catalog is {
  entity Product is {
    // Product definition
  }
  entity Category is {
    // Category definition
  }
}

Containment Rules

The included content must be valid for the location where it's included. RIDDL enforces the definition hierarchy:

Include Location Valid Included Content
Root level Domains, modules
Domain Contexts, types, epics, users
Context Entities, repositories, sagas, types
Entity States, handlers, functions

Including content that violates the hierarchy produces a validation error.

File Organization Patterns

By Bounded Context

myproject/
├── main.riddl
├── contexts/
│   ├── sales.riddl
│   ├── inventory.riddl
│   └── shipping.riddl
└── shared/
    └── common-types.riddl

By Definition Type

myproject/
├── main.riddl
├── types/
│   └── domain-types.riddl
├── entities/
│   ├── customer.riddl
│   └── order.riddl
└── epics/
    └── user-journeys.riddl

Best Practices

  1. Use meaningful paths: Organize files to reflect your domain structure
  2. Keep files focused: One context or major entity per file
  3. Share types carefully: Common types should be truly universal
  4. Document dependencies: Note which files depend on which

Occurs In

All vital definitions (domains, contexts, entities, etc.)

Contains

Content relevant to the definition in which it is used. The included content must conform to the hierarchy shown in the index.