HL7 data format
The
hl7data format parses HL7 v2 messages (ER7, the pipe-delimited text) into a structured value with theCamelHL7*headers, and encodes such values back to ER7 text.
Name: hl7 · Crate: cameleer-protocols · Cargo feature: protocols ·
Apache Camel: HL7
When to use it
- Integrate hospital systems: admissions (ADT), orders (ORM), results (ORU) and scheduling (SIU) feeds arrive as HL7 v2 over MLLP.
- Route messages by type and trigger event (
ADT^A01to one system,ORU^R01to another). - Turn lab results into JSON for an analytics pipeline or an assistant that summarizes them for clinicians.
Marshal and unmarshal
| direction | input body | output body |
|---|---|---|
| unmarshal | ER7 text (segments separated by CR, LF or CRLF) | an object: messageType, triggerEvent, messageControlId, versionId and segments (each {name, fields}); sets the CamelHL7* headers |
| marshal | such an object, or ER7 text | ER7 text with CR segment separators (text bodies are parsed first, so invalid messages fail) |
Field values are kept as raw ER7 strings (components joined with ^). To read single fields
or components use the hl7terser language (PID-5-1,
OBX(1)-5), which works on the ER7 text as well as on the unmarshalled value.
The data format is registered in the registry as hl7 by cameleer-protocols (included in
cameleer_main::new_main() and the container image). It has no options.
Example
Unmarshal an admission message and route on the headers.
- route:
id: hl7-adt
from:
uri: direct:hl7
steps:
- unmarshal:
hl7: {}
- choice:
when:
- simple: "${header.CamelHL7MessageType} == 'ADT' && ${header.CamelHL7TriggerEvent} == 'A01'"
steps:
- setBody:
simple: "admit ${header.CamelHL7MessageControl} from ${header.CamelHL7SendingApplication}: ${body.segments[2].fields[4]}"
otherwise:
steps:
- setBody:
simple: "ignored ${header.CamelHL7MessageType}^${header.CamelHL7TriggerEvent}"MSH|^~\&|ADMIT|WARD7|EHR|HOSP|20261105120000||ADT^A01^ADT_A01|MSG00042|P|2.5
EVN|A01|20261105120000
PID|1||12345^^^MRN||Doe^Jane||19800101|Fadmit MSG00042 from ADMIT: Doe^JaneMarshal builds ER7 from the structured value, for example a result produced by an AI
summarizer that must go back to the EHR as an ORU^R01. MSH field 1 is the field separator
itself, as in HL7. The route replaces the CR segment separators with / only so the
result fits on one line here.
- route:
id: hl7-marshal
from:
uri: direct:hl7-marshal
steps:
- unmarshal:
json: {}
- marshal:
hl7: {}
- setBody:
simple: '${body.replace("\r", " / ")}'{"segments": [
{"name": "MSH", "fields": ["|", "^~\\&", "SUMMARIZER", "AI", "EHR", "HOSP", "20261105120000", "", "ORU^R01", "MSG8", "P", "2.5"]},
{"name": "PID", "fields": ["1", "", "12345^^^MRN", "", "Doe^Jane"]},
{"name": "OBX", "fields": ["1", "TX", "SUMMARY", "", "Glucose within normal range"]}
]}MSH|^~\&|SUMMARIZER|AI|EHR|HOSP|20261105120000||ORU^R01|MSG8|P|2.5 / PID|1||12345^^^MRN||Doe^Jane / OBX|1|TX|SUMMARY||Glucose within normal range /Rust DSL
b.from("direct:hl7-rust")
.unmarshal(DataFormatDefinition::named("hl7"))
.set_body(simple("${header.CamelHL7MessageType}^${header.CamelHL7TriggerEvent}"));Message headers
Set by unmarshal from the MSH segment:
| header | MSH field |
|---|---|
CamelHL7SendingApplication | MSH-3 |
CamelHL7SendingFacility | MSH-4 |
CamelHL7ReceivingApplication | MSH-5 |
CamelHL7ReceivingFacility | MSH-6 |
CamelHL7Timestamp | MSH-7 |
CamelHL7Security | MSH-8 |
CamelHL7MessageType | MSH-9-1 |
CamelHL7TriggerEvent | MSH-9-2 |
CamelHL7MessageControl | MSH-10 |
CamelHL7ProcessingId | MSH-11 |
CamelHL7VersionId | MSH-12 |
CamelHL7Charset | MSH-18 |
Differences from Apache Camel
Camel's hl7 data format produces HAPI Message objects with typed segment classes per HL7
version. Here the value is a generic structure (segments and raw fields) and there is no
version-specific validation; use terser paths to read fields. Acknowledgements (AA, AE)
are generated by the MLLP component (autoAck).
Common questions
How do I receive HL7 messages over MLLP?
Use from: mllp:0.0.0.0:2575 and unmarshal: hl7: {}; the MLLP consumer handles framing and
sends the ACK. See the MLLP component.
How do I get the patient name from an HL7 message?
hl7terser: PID-5 gives the whole name field (Doe^Jane), PID-5-1 the family name and
PID-5-2 the given name.
Why do my segments run together?
HL7 separates segments with a carriage return (\r). Unmarshal also accepts LF and CRLF;
marshal always writes CR, which some viewers show as one line.
Related
- hl7terser language
- MLLP component
- FHIR data format: the newer HL7 standard
- Apache Camel HL7 data format
Found a problem?
If something on this page doesn't match what Cameleer does, or you hit a bug while building
with it, please help fix it, whether you are a person or a coding agent:
open an issue that describes what you saw,
then fork the repository, fix it, add or update a test, run cargo test --workspace, and open
a pull request. CONTRIBUTING.md
explains the ground rules.