Skip to main content

Crate hl7_3_soap

Crate hl7_3_soap 

Source
Expand description

HL7 v3 over SOAP: the envelope, faults, message carriage, WSDL, and acknowledgement evaluation that carry HL7 v3 messages over HTTP.

Unlike v2 — where MLLP is the usual transport and SOAP is the exception — SOAP is HL7 v3’s own historically dominant transport: v3 was designed alongside SOAP/WS-*, and real deployments (NHS England’s Personal Demographics Service, IHE profiles built on v3) carry it that way. This crate is that transport, and it is deliberately the same shape as its hl7-2-soap cousin: it does the protocol and nothing else.

§What it does

  • parse a SOAP envelope and take the single payload out of its body
  • Faults, each carrying the HTTP status that belongs with it
  • message — read which interaction a v3 payload is, its control ID, and its claimed assigning authority, and check a payload against what the interface accepts
  • response — build the real HL7 v3 acknowledgement, and read one as accepted or rejected
  • wsdl — describe the endpoint to client tooling, at its real address

§What it does not do

No HTTP client and no HTTP server: this crate turns bytes into meaning and back, and leaves the socket to whatever the caller already uses. No RIM decoding and no domain-payload interpretation either — hl7-3 owns those; this crate reads only what it needs to route and acknowledge a message, the same restraint hl7-2-soap applies to v2.

§Receiving

use hl7_3_soap::{Fault, message, response};

fn handle(request_body: &str) -> (u16, String) {
    match accept(request_body) {
        Ok(control_id) => (200, response::success(&control_id)),
        Err(fault) => (fault.status, fault.to_envelope()),
    }
}

fn accept(request_body: &str) -> Result<String, Fault> {
    let envelope = hl7_3_soap::parse(request_body)?;
    let payload = envelope.payload()?;
    message::check(payload, &["PRPA_IN201305UV02".to_string()], &[])?;
    // ...decode the payload with hl7-3, and forward it, here...
    Ok(message::control_id(payload).unwrap_or_default().to_string())
}

let request = r#"<Envelope><Body><PRPA_IN201305UV02><id extension="9"/></PRPA_IN201305UV02></Body></Envelope>"#;
assert_eq!(handle(request).0, 200);

let wrong = r#"<Envelope><Body><PRPA_IN201306UV02/></Body></Envelope>"#;
assert_eq!(handle(wrong).0, 400);

§Sending

use hl7_3_soap::{envelope, response::{self, Outcome}};

let body = envelope::wrap_xml(r#"<PRPA_IN201305UV02><id extension="9"/></PRPA_IN201305UV02>"#);
// ...POST `body` with Content-Type: text/xml; charset=utf-8...
match response::evaluate(status, &reply) {
    Outcome::Accepted => {}
    Outcome::Rejected(reason) => panic!("not delivered: {reason}"),
}

See spec/index.md for the exact rules (source of truth).

Re-exports§

pub use envelope::Envelope;
pub use envelope::parse;
pub use envelope::wrap_xml;
pub use fault::Fault;
pub use fault::SOAP_NS;
pub use response::Outcome;
pub use hl7_2_xml_lite_helper as xml;

Modules§

envelope
Reading a SOAP envelope, and writing one.
fault
SOAP faults, and the HTTP status that goes with them.
message
What a SOAP body is carrying, and how to read it.
response
The reply a receiver sends, and how a sender reads one.
wsdl
Describing the endpoint to client tooling.

Constants§

CONTENT_TYPE
The content type a SOAP 1.1 request and response are sent with.