edi://¶
Producer that parses EDI (and the other formats omniparser understands — CSV, fixed-length, XML, JSON) into JSON, and generates ANSI X12 interchanges from a structured payload.
Parsing is powered by omniparser, a native-Go streaming ETL engine driven by a JSON schema (schema version omni.2.1). omniparser handles things a naive split-on-delimiter parser cannot: hierarchical segment groups / loops, component / repetition delimiters, release / escape characters, occurrence validation, and field-level transforms via XPath + custom funcs. When no schema is supplied the component falls back to a schemaless structural parse (segment / element split) for quick inspection.
Generation produces an X12 interchange (ISA / GS / ST … SE / GE / IEA) from a structured payload. omniparser is parse-only, so this path is hand-rolled.
Producer-only — CreateConsumer returns ErrConsumerNotSupported.
URI shape¶
edi://<name>?op=parse&schema=schemas/x12_214.json
edi://<name>?op=parse&dialect=edifact # schemaless structural parse
edi://<name>?op=generate&senderId=ME&receiverId=YOU&version=00501
The <name> segment is a logical label (used in caching + logs). It doesn't need to match any external identifier.
Parameters¶
| Param | Type | Default | Producer/Consumer/Both | Description |
|---|---|---|---|---|
op |
enum | parse |
Producer | parse (EDI → JSON via omniparser) or generate (structured payload → X12 interchange). |
schema |
string | — | Producer | Path to an omniparser JSON schema. Drives op=parse. Mutually exclusive with schemaInline. |
schemaInline |
string | — | Producer | Inline omniparser JSON schema (URL-encoded). |
dialect |
enum | x12 |
Producer | Delimiter preset for schemaless parsing and X12 generation: x12 or edifact. |
skipErrors |
boolean | false |
Producer | On op=parse, skip records that fail transform (continuable errors). Count surfaces in the edi.error_count header. |
unwrap |
boolean | false |
Producer | On op=parse, if exactly one record is produced, set the body to that object rather than a one-element array. |
senderId |
string | — | Producer | op=generate: ISA06 / GS02. |
receiverId |
string | — | Producer | op=generate: ISA08 / GS03. |
version |
string | 00501 |
Producer | op=generate: X12 version. ISA12 uses the first 5 chars; GS08 is padded to 6 (00501 → 005010). |
functionalId |
string | PO |
Producer | op=generate: GS01 functional identifier code (PO, SH, IN, QM, ...). |
usageIndicator |
enum | P |
Producer | op=generate: ISA15. P=production, T=test. |
elementSeparator |
string | dialect default | Producer | Override element separator (x12 *, edifact +). |
segmentTerminator |
string | dialect default | Producer | Override segment terminator (x12 ~, edifact '). |
componentSeparator |
string | : |
Producer | Override component separator. |
repetitionSeparator |
string | U |
Producer | op=generate: ISA11 value. |
Schema source resolution (op=parse)¶
- URI param
schema=<file path> - URI param
schemaInline=<raw JSON>(URL-encoded) - Exchange header
edi.schema(inline JSON) - Exchange header
edi.schemaPath(file path) - None → schemaless structural parse
Headers¶
| Header | Direction | Description |
|---|---|---|
edi.schema |
Read | Inline omniparser schema (per-exchange override). |
edi.schemaPath |
Read | File path to omniparser schema. |
edi.engine |
Written | omniparser (schema-driven) or structural (schemaless fallback). |
edi.operation |
Written | parse or generate. |
edi.record_count |
Written | parse — record count. |
edi.error_count |
Written | parse — count of skipped per-record errors (when skipErrors=true). |
edi.segment_count |
Written | parse (structural only) — number of segments. |
edi.transaction_set |
Written | generate — transaction set id (e.g. 850). |
edi.control_number |
Written | generate — ISA13 control number. |
Content-Type |
Written | application/json (parse) or application/edi-x12 (generate). |
Examples¶
Schema-driven parse:
workflows:
- id: x12-214-parse
trigger:
uri: file:///inbound/?include=.*\.edi$&move=processed
steps:
- target: edi://x12-214?op=parse&schema=schemas/x12_214.json&unwrap=true
- target: direct://route-shipment-status
Schemaless inspection of an EDIFACT file:
- target: edi://inspect?op=parse&dialect=edifact
- log: { message: "got an EDIFACT interchange", level: INFO }
Generate an X12 850 (purchase order):
- set-body:
starlang: |
%sl 2.0
output application/json
input payload
---
{
"transaction_set": "850",
"segments": [
{ "segment_id": "BEG", "elements": ["00", "SA", payload.po, "", payload.date] },
{ "segment_id": "REF", "elements": ["DP", payload.dept] },
{ "segment_id": "PER", "elements": ["BD", payload.contact] }
]
}
- target: edi://orders-out?op=generate&senderId=ACME&receiverId=VENDOR&version=00501&functionalId=PO
Use a schema chosen at runtime via header:
- set-header:
name: edi.schemaPath
starlang: 'lookup_schema(header("Content-Type"))'
- target: edi://parse-any?op=parse
Behavior notes¶
- Schema caching —
omniparser.Schemais thread-safe and reusable; the endpoint caches one schema per unique schema content (schemaMu+schemaCache). - Schemaless fallback delimiters — driven by
dialect. If the configured terminator isn't found in the input, the parser falls back to newline splitting (common in samples). - Continuable errors — only per-record
ErrTransformFailedis skipped whenskipErrors=true; everything else aborts immediately (otherwise the loop would repeat forever on a fatal input issue). - Generation is hand-rolled — omniparser doesn't generate. The X12 builder emits ISA / GS / ST → body segments → SE / GE / IEA, with
\nafter each~-terminated segment for readability. Customise viaelementSeparator/segmentTerminatoroverrides. unwrapis a per-exchange convenience for upstream steps that expect a single object rather than a one-element array.
Source¶
pkg/component/edi/edi.go, pkg/component/edi/starlang_func.go (Helix-bridge omniparser extension exposing starlang as a custom_func).
See also¶
- Connectors / EDI — additional EDI-adjacent integrations.
- chart, pdf, template — other producer-only domain components.