ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

Message Translator

The most pervasive pattern in any EDI integration: convert a message from a source schema to a target schema. Hohpe canonised it in 2003; the code has not changed much since — but the discipline has.

Problem

EDI is defined by the plurality of its formats: EDIFACT in Europe, X12 in North America, cXML at Coupa and Ariba, UBL at PEPPOL, IDoc on the SAP side. No partner speaks a single format. To integrate ORDERS received from 200 suppliers across 4 different formats into one ERP, you must translate — often into an internal canonical model — then re-translate towards the target.

Forces

  • Asymmetric semantics. Two formats may carry "the same information" in radically different structures. EDIFACT bundles quantity and unit in QTY+21:24:PCE; JSON splits them. UBL uses cbc:BaseQuantity with attribute unitCode.
  • Missing information. The target may require a field the source does not carry. Either enrich (see Content Enricher) or apply a documented default.
  • Information loss. Conversely, the source may carry fields the target ignores. Decision: keep them in a trace field, or drop them explicitly. Never silently.
  • Maintainability. A translation "map" is a software asset that survives versions. It must be versioned, tested, audit-closed.

Solution

Hohpe (EIP §85) prescribes a pure component, with no business state, that takes a message in format A and returns the same message in format B — nothing more. The translation is structural (the schema changes) and sometimes semantic (values are transformed: an EDIFACT date "20260514" becomes "2026-05-14" ISO, a quantity with unit PCE becomes EA per a UN/CEFACT REC 20 mapping table).

plaintext topology.txt
EDIFACT ORDERS                  Canonical JSON
   ──────────────                  ──────────────
   UNH+1+ORDERS:...      ┌──────┐  {
   BGM+220+PO-001        │ M.T. │    "header": {
   DTM+137:20260514   ──▶│      │──▶   "type": "ORDER",
   NAD+BY+8712345600014  │      │      "number": "PO-001",
   LIN+1++4006381...     └──────┘      ...
   QTY+21:24:PCE                     }

Topology

Two main topologies:

  • Point-to-point. A direct translation between each source/target pair. Simple to start with 2-3 partners, becomes unmanageable above — the famous n × m mapping problem.
  • Hub-and-spoke (canonical). Each format is translated to a common canonical, then each target format is generated from that canonical. The cost of adding a partner becomes O(1) instead of O(n). See the Canonical Model pattern.

EDI implementation

The most emblematic example: translating an EDIFACT D.96A ORDERS to an internal canonical JSON.

edifact orders-edifact.edi
UNH+1+ORDERS:D:96A:UN:EAN008'
BGM+220+PO-12345+9'
DTM+137:20260514:102'
NAD+BY+8712345600014::9'
NAD+SU+5412345600015::9'
LIN+1++4006381333931:EN'
QTY+21:24:PCE'
PRI+AAA:12.50'
UNT+8+1'

The canonical equivalent:

json order-canonical.json
{
  "schemaVersion": "1.0",
  "header": {
    "type": "ORDER",
    "number": "PO-12345",
    "date": "2026-05-14",
    "buyer": { "gln": "8712345600014" },
    "supplier": { "gln": "5412345600015" }
  },
  "lines": [
    {
      "position": 1,
      "item": { "gtin": "4006381333931" },
      "quantity": { "value": 24, "uom": "PCE" },
      "price": { "value": 12.50, "currency": "EUR" }
    }
  ],
  "sourceTrace": {
    "format": "EDIFACT/D96A/ORDERS",
    "interchange": "ORD202605140001"
  }
}

Three interesting translations:

  • Date. DTM+137:20260514:1022026-05-14. Qualifier 102 indicates the CCYYMMDD format; reformat to ISO 8601.
  • Partner identifier. NAD+BY+8712345600014::9buyer.gln. Composite C082 contains identifier + agency qualifier (9 = EAN/GS1). Either keep the qualifier in the target, or elide it if the target has only one identifier type.
  • Quantity with unit. QTY+21:24:PCE{ "value": 24, "uom": "PCE" }. Qualifier 21 (Ordered quantity) is here implicit through context (QTY segment inside an ORDERS LIN).

Reversibility

A translation is reversible if you can reconstruct the source from the target without loss. In EDI, pure reversibility is rare: source formats often have optional or redundant fields that translation normalises. The pragmatic rule: byte-level reversibility is not needed, but we must be able to reconstruct a message semantically equivalent. That allows re-generating an EDIFACT INVOIC from canonical to answer a partner that only speaks EDIFACT.

Anti-patterns

  • Partner-to-partner direct translation. 200 partners × 4 formats = 200 × 199 possible translations. Canonical reduces to 200 ins + 200 outs.
  • Magic strings in code. The mappings (EDIFACT qualifier → canonical field) must be declarative — tables or DSL — not procedural code buried in implementation.
  • Silence on dropped fields. If translation abandons information, the log must record it explicitly. Otherwise audit will never know why such-and-such EDIFACT field disappears.
  • Test by specific cases only. Tests must cover combinatorics — qualifiers, optional segments, cardinalities. Translation bugs hide in rare combinations.
  • Implicit versioning. EDIFACT D.96A and D.01B do not have the same NAD structure. A single "EDIFACT" translation that ignores the version always breaks eventually.
  • Canonical Model — the pivot format we translate to.
  • Normalizer — the pattern that orchestrates several Message Translators based on detected format.
  • Content Enricher — when translation needs external data.

Sources

  • Hohpe G., Woolf B. — Enterprise Integration Patterns, Message Translator (§85). enterpriseintegrationpatterns.com — Message Translator
  • UN/CEFACT — Recommendation 20. Unit-of-measure codes (PCE, EA, KGM...) and international cross-reference tables. unece.org — Recommendation 20
  • OASIS UBL 2.1 — Annex C. Semantic mapping tables between UBL and EDIFACT concepts (Cross Industry Invoice).
  • SAP — IDoc ORDERS05. Documentation of IDoc target structures and their mapping to EDIFACT ORDERS (OSS note 23).