Adaptor
An adaptor's purpose is to adapt one Context to another Context. In Domain-Driven Design, this concept is known as an anti-corruption layer that keeps the ubiquitous language of one context from "corrupting" the language of another context. The authors of RIDDL didn't like that term for a variety of reasons so we have renamed the concept as adaptor in RIDDL. Same idea, different name.
Message Translation¶
Adaptors do their work at the level of messages sent between Contexts. This is done using one or more Handlers. Each handler specifies how messages are translated into other messages and forwarded to the target context.
Target Context¶
Adaptors are only definable within a containing Context which provides one participant of the translation. The other Context, known as the target context, is specified within the definition of the adaptor.
Adaptation Directionality¶
Adaptors only translate in one direction, between the containing context and the target context. However, multiple Adaptors can be defined to achieve bidirectional adaptation between Contexts. The directionality of an Adaptor is specified in the definition of the adaptor. This leads to two kinds of adaptors: inbound and outbound.
Inbound Adaptors¶
Inbound adaptors provide an adaptation that occurs from the Context referenced in the adaptor to the Context containing the adaptor.
Outbound Adaptors¶
Outbound adaptors provide an adaptation that occurs from the Context containing the adaptor to the Context referenced in the adaptor.
Syntax¶
context Orders is {
adaptor PaymentAdapter from context Payments is {
handler InboundPayments is {
on paid: event Payments.PaymentCompleted {
tell command MarkAsPaid(paid.orderId) to entity Order
}
on event Payments.PaymentFailed {
tell command HandlePaymentFailure to entity Order
}
on other {
error "Unrecognized message from the Payments context"
}
}
} with {
briefly as "Translates payment messages between Orders and Payments"
}
adaptor InventoryAdapter to context Inventory is {
handler OutboundInventory is {
on command ReserveItems {
tell command Inventory.ReserveStock to context Inventory
}
on other {
error "Unrecognized outbound message"
}
}
} with {
briefly as "Translates inventory requests from Orders to Inventory"
}
}
Note the operand order: tell <message> to <processor>, not the reverse.
The Isolation Seam¶
An adaptor bridges exactly two contexts: the context that contains it, and
the referent context named in its declaration. It is the only sanctioned
crossing point between contexts, so it must not traffic in a third
context's messages.
Validation
Errors:
- A message whose owning context is neither the parent nor the referent.
This applies both to the message an
onclause consumes and to everysend/telltarget it emits, including those nested insidewhen,matchandforeachbodies. - A handler with no
on otherclause. An adaptor must say explicitly what it does with messages it does not recognize, rather than discarding them silently.
Types defined at domain or root level are shared vocabulary common to both sides and are never flagged.
Options¶
circuit-breaker (0–2 arguments) is valid on an adaptor, tripping the
adaptation when the far side is failing.
When to Use Adaptors¶
Use an adaptor when:
- Contexts have different vocabularies: The same concept has different names or structures in each context
- You need to protect domain integrity: Prevent external concepts from leaking into your bounded context
- Contexts evolve independently: Changes in one context shouldn't force changes in another
- Integration with external systems: Translate between your domain model and external APIs
Example scenario: Your Orders context tracks "line items" while the Inventory context uses "stock reservations". An adaptor translates between these models so neither context needs to know about the other's terminology.
Adaptor vs. Direct References¶
| Approach | When to Use |
|---|---|
| Adaptor | Contexts have different models, need translation |
| Direct reference | Contexts share the same model, tightly coupled by design |
Occurs In¶
Contains¶
- Handlers
- Functions, Types, Constants, Invariants
- Inlets and Outlets
- Versions and Copyrights