Internal canonical model
Without a pivot, every new partner adds as many mappings as you have target systems. With a pivot, you only ever map to the pivot. The cost is linear instead of quadratic.
Problem — the n × m mapping
An EDI platform must, by construction, talk to several partners (each with their own standard: EDIFACT, X12, UBL, cXML) and feed several target systems (ERP, WMS, TMS). If every mapping is written directly from partner to system, the result is a Cartesian product: with 10 partners and 4 systems, that is 40 mappings to maintain. Adding a partner adds 4 mappings; adding a system adds 10. That n × m growth is unsustainable beyond a few years.
Without canonical — n × m mapping:
Partner A (EDIFACT) ┐ ┌─── ERP X
Partner B (X12) ├── 12 mappings ─┤
Partner C (cXML) │ (3 × 4) ├─── ERP Y
Partner D (UBL) ┘ └─── ERP Z
With canonical — n + m mapping:
Partner A ──┐ ┌── ERP X
Partner B ──┤ ├── ERP Y
Partner C ──┼─► CANONICAL ─────┤
Partner D ──┘ (1 schema) └── ERP Z
→ 7 mappings instead of 12 (4 IN + 3 OUT) Forces
- Real partner heterogeneity. You can't force every partner onto a single standard — they stay on their EDIFACT D.96A legacy, X12 .004010 or cXML 1.2.069.
- Real system heterogeneity. ERP, WMS, BI and customer portal each have their own internal schema, often dictated by the vendor (SAP IDoc, NetSuite REST, Salesforce SOQL).
- Semi-annual evolutions. EDIFACT and X12 ship two releases per year. Without a pivot, every update propagates across all outbound mappings.
- Stability of the pivot. The canonical model has to evolve slower than the periphery, otherwise it loses its value. That is a strong design constraint.
Solution: a canonical in the middle
The Canonical Data Model pattern (Hohpe & Woolf, 2003) prescribes a single internal schema — the canonical — used as a pivot between peripherals. Each partner has an IN mapping translating its format to the canonical, and each target system has an OUT mapping translating the canonical to its internal format. The canonical itself is never exposed.
The canonical is typically defined in JSON Schema (Draft 2020-12) or XSD. JSON makes modern tooling easier (generated TypeScript types, Zod/Ajv validation), but XSD remains a better fit when aligning to a public canonical (OAGi BODs, UBL).
Example of a canonical ORDER JSON
Here is what a minimal pivot order can look like:
{
"$schema": "https://ediverse.example.com/schemas/order/v3",
"kind": "Order",
"version": "v3",
"header": {
"id": "ORD-2026-00187",
"issuedAt": "2026-05-14T10:18:00Z",
"currency": "EUR",
"buyer": {
"gln": "5410000000123",
"name": "North Textile Cooperative",
"address": { "country": "FR", "city": "Lyon" }
},
"seller": {
"gln": "5410000000456",
"name": "Atelier Marchand SARL"
}
},
"lines": [
{
"id": "1",
"itemId": { "scheme": "gtin", "value": "3520000001234" },
"description": "Unbleached canvas 220 g/m²",
"quantity": { "value": 120, "unit": "MTR" },
"unitPrice": { "value": 18.00, "currency": "EUR" }
}
]
} Key principles:
- Typed identifiers.
itemIdhas an explicitscheme(gtin,sap-mat, …). This prevents mixing GTIN and internal SKU eighteen months down the line. - Versioned canonical. The
v3in the schema marks the third revision. Older v2 mappings can coexist during a migration window. - Explicit units.
quantity.unitin UN/ECE Recommendation 20 codes (MTR= metre,PCE= piece). Never assume a default unit. - No untyped optional field. If a partner has an
uncovered business need, add an explicit field to the canonical — do
not allow a free-form
extrasub-object.
Off-the-shelf — OAGi BODs and UBL
Rather than invent a canonical, you can adopt a public one:
- OAGi BODs (Business Object Documents) — Open Applications Group, since 1995. Catalogue of more than 700 BODs covering orders, invoices, payments, HR, manufacturing. Adopted by Oracle Fusion and SAP S/4HANA as an integration schema. oagi.org
- UBL (Universal Business Language) — OASIS, version 2.4 (2023). More oriented toward billing/procurement, technical foundation of PEPPOL BIS Billing 3.0. docs.oasis-open.org/ubl
Both come with a stable maintainer and a tooled community (parsers, validators). Drawback: they are large and usually cover more than what you want internally. Common practice is to profile a public canonical, i.e. extract a documented subset that becomes the internal canonical.
Governance of the canonical
The pattern only works if the canonical is governed like a public API:
- Semantic versioning.
v1,v2, … with clear rules for breaking changes (new major) vs additive ones (minor). - Migration window. When
v3ships,v2stays supported for 6 to 12 months. Existing IN/OUT mappings don't have to migrate the same weekend. - Validation on entry and exit. An IN mapping that produces an invalid canonical must be rejected before any business processing. An OUT mapping consuming a canonical must validate it on entry.
- Derived documentation. The canonical is the single source of truth: schemas, TypeScript types, partner docs and integration tests are all generated from it. No manual copies.
Anti-patterns
- Catch-all canonical. A schema with
customFields: Record<string, any>where each mapping dumps whatever it wants. No more typing, no more guarantee: that is not a canonical, that is a backpack. - Canonical = vendor format. Adopting SAP IDoc as the canonical because everything flows through SAP is tempting and catastrophic the day SAP is replaced. The canonical must be vendor neutral.
- Implicit versioning. Adding a mandatory field without bumping the version silently breaks every existing mapping.
- Direct partner → system mapping bypassing the canonical "to go faster". You rebuild the n × m you wanted to avoid.
- Over-rich canonical. Importing UBL whole into your internal canonical without profiling gives you 600+ elements 95% of which serve no purpose — each mapping becomes an exegesis.
Related patterns
- Acknowledgements — the business ACK returned to the partner is generated from the canonical.
- Exception flow — canonical invalidation is one of its entry points.
Sources
- Hohpe G., Woolf B. — Enterprise Integration Patterns, Canonical Data Model, the source pattern. enterpriseintegrationpatterns.com — Canonical Data Model
- OAGi — Open Applications Group. Business Object Documents catalogue. oagi.org
- OASIS — UBL 2.4 (2023). Universal XML schema for commercial documents. docs.oasis-open.org/ubl/UBL-2.4.html
- UN/ECE Recommendation 20 — unit of measure codes (kg, MTR, PCE, …). Reference for typed quantities in any canonical. unece.org/trade/uncefact/cl-recommendations
- JSON Schema Draft 2020-12. The dominant schema standard for modern canonicals. json-schema.org