Middleware
Wrap SAP IDoc output in a modern REST + canonical layer so downstream systems stop parsing IDoc segments directly.
IDoc segments are positional, versioned, and unforgiving; every consumer that parses them directly is a break waiting to happen. Land IDocs into a middleware tier, translate each message type (e.g. MATMAS, DEBMAS) into a canonical JSON resource, and publish it over REST. Consumers bind to the canonical contract, not the IDoc.
A working piece from this integration — no sign-up. The full build handles the edge cases, safeguards, and cutover.
/* SAP MATMAS03 IDoc → Canonical Material REST payload mapping */ SAP_IDoc_Raw (MATMAS03) → Canonical_Rest_JSON ----------------------------------------------|-------------------------------- EDI_DC40-IDOCTYP → data.type = "Material" EDI_DC40-MESCOD → data.partitionCode E1MARAM-MATNR → data.materialNumber E1MARAM-MEINS → data.baseUnit.code E1MARAM-MATKL → data.materialGroup E1MARCM-WERKS → data.plants[].plantId E1MARCM-LVORM → data.plants[].isMarkedForDeletion E1MAKTM-SPRAS → data.descriptions[].language E1MAKTM-MAKTX → data.descriptions[].text /* Transformation middleware (pseudo-Java): */ IdocSegment dc40 = idoc.getSegment("EDI_DC40"); IdocSegment maram = idoc.getSegment("E1MARAM"); List<IdocSegment> plants = idoc.getSegments("E1MARCM"); CanonicalMaterial material = CanonicalMaterial.builder() .type("Material") .materialNumber(maram.getField("MATNR")) .baseUnit(Unit.of(maram.getField("MEINS"))) .partitionCode(dc40.getField("MESCOD")) .build(); plants.forEach(p -> material.addPlant( p.getField("WERKS"), "X".equals(p.getField("LVORM")) ));
How we'd take this from discovery to a production-safe cutover — the phases, the canonical mapping, and the edge cases that bite.
This integration wraps SAP IDoc output in a canonical REST publishing layer, replacing fragile point-to-point IDoc parsing in downstream consumers. The pathway covers extraction from SAP ECC, transformation to a technology-agnostic canonical model, and exposure via a versioned REST API with event-driven notification.
E1EDK01.BSTYP → documentType). Version the schema (e.g., 2.1.0) and publish to the enterprise API registry before coding begins.STAT status codes. Enable the ProcessingMode as Collect Messages if batching is needed. Map the SAP Message Type to the integration flow; set idocType and basicType parameters to match the profile from WE20.E1EDP01 line items) by mapping to a JSON array. Convert SAP date formats (YYYYMMDD, YYYYMMDDHHMMSS) to ISO-8601. Translate EDIDC.PRNAM (processing program) and EDIDC.MESGF (message function) into canonical metadata fields. Add a sourceSystem: "SAP-ECC" and sourceId: "IDOC_NUM" envelope to every message.https://api.company.com/canonical/v2/events) with OAuth 2.0 client credentials. Configure rate limiting per consumer client ID. Enable request/response logging to a SIEM-compatible audit store (Splunk, ELK) without persisting sensitive payload fields. Set up a separate GET endpoint for event replay: GET /canonical/v2/events/{eventId}.eventId, eventType, timestamp, and sourceId — never the full canonical payload — so consumers pull by reference. This decouples delivery from processing.EDIDS.STAMID status codes ≥ 28 (error). Implement a manual repair flow that resubmits from the DLQ after XSLT or mapping correction.| Canonical Field | IDoc Segment | IDoc Field | Notes |
|---|---|---|---|
documentId | EDI_DC40 | DOCNUM | Unique IDoc number; use as eventId seed |
documentType | E1EDK01 | BSTYP | Order, Quotation, etc.; map to canonical enum |
partnerName | E1EDKA1 | NAME1 | Qualifier AG (sold-to) or RE (bill-to) |
lineItems[] | E1EDP01 | POSEX | Array; map each E1EDP01 to one array element |
netAmount | E1EDK02 | NETWR | Sum of all line net values; currency from WAERS |
creationDateTime | EDI_DC40 | CREA | Convert from YYYYMMDDHHMMSS to ISO-8601 |
exchangeCode | E1EDK03 | EXCHA | Only present on cross-company transactions |
null or skip the field rather than throw a null-pointer, or downstream validators will reject every message.DATS (8-char) and the source sends 2024010 (7-char) due to a leading-zero drop bug, the ISO-8601 conversion silently drops the day instead of failing loudly.004 (change) or 005 (cancel) arrive without a full replacement payload; the canonical event type must reflect the reversal, not the original document structure.EDIDC.DOCNUM ranges from SAP (transaction BD87) and compare against the canonical event log. A row-count match at the aggregate level, combined with sampling 5% of document IDs for field-level diff, constitutes a valid reconciliation gate. Keep the SAP IDoc port active for 90 days post-cutover as a shadow fallback; if the canonical layer reports error rates above the 0.1% threshold, redirect consumers back to the legacy feed without requiring a redeployment. Store the final mapping version number in the message envelope (mappingVersion: "2.1.0") so historical events can be replayed through the correct transformer if schema evolution breaks backward compatibility. Reading the reference is free. Delivering it under liability — with the safeguards that keep production running through the cutover — is what we do.