cannectors

SOAP

Raw XML SOAP calls, SOAP 1.1/1.2 bindings, MTOM, WS-Security, and response parsing.

Cannectors supports SOAP without WSDL code generation. You provide the raw XML fragment that belongs inside <soap:Body>, then the runtime builds the envelope, applies templating, sends the request, and parses the XML response back into records.

Use the SOAP modules when an integration exposes SOAP operations but you still want the same pipeline model as HTTP modules: polling, per-record enrichment, or output delivery.

Runtime model

There is no WSDL parsing at runtime. The WSDL remains a design-time artifact you can inspect with a vendor document, SoapUI, or Postman. In the pipeline, configure:

endpoint: https://soap.example.com/orders
soapVersion: "1.1"
soapAction: urn:SubmitOrder
operation: SubmitOrder
body: |
  <m:SubmitOrder xmlns:m="urn:orders">
    <m:OrderId>{{record.orderId}}</m:OrderId>
  </m:SubmitOrder>

operation is a logical name for logs and observability. The actual SOAP payload is the XML in body, plus soapAction when the service requires it.

SOAP 1.1 vs 1.2

Set soapVersion to "1.1" or "1.2". The default is "1.1".

SettingSOAP 1.1SOAP 1.2
Envelope namespacehttp://schemas.xmlsoap.org/soap/envelope/http://www.w3.org/2003/05/soap-envelope
HTTP content typetext/xml; charset=utf-8application/soap+xml; charset=utf-8; action="..."
SOAP actionSOAPAction headeraction parameter on Content-Type
Fault shapefaultcode, faultstring, detailCode, Reason, Detail

Do not set your own Content-Type or SOAPAction in httpHeaders. The SOAP client owns those headers so the binding stays consistent with soapVersion.

XML templating

SOAP body, SOAP header fragments, endpoint, HTTP headers, MTOM contentId, and WS-Security credentials can be templated with record values. Text inserted into XML is escaped at runtime, so a value containing <, &, or </Body> remains text rather than becoming markup.

body: |
  <m:GetCustomer xmlns:m="urn:customers">
    <m:CustomerId>{{record.customerId}}</m:CustomerId>
  </m:GetCustomer>

The template engine also supports defaults:

<m:Cursor>{{record.pagination.cursor | default: ""}}</m:Cursor>

If you need XML elements or attributes as markup, write them directly in the template. Record substitutions are for values.

Response paths

SOAP responses are parsed as XML maps. dataField selects the sub-tree that becomes records or the value to merge:

dataField: Envelope.Body.ListOrdersResponse.Orders.Order

Namespaces are decoded according to the XML parser's map output. In most raw responses the path starts with Envelope.Body...; when an upstream preserves namespace prefixes in element names, include those names exactly as they appear in the parsed response.

If dataField is omitted on soap_call, the whole parsed SOAP response is merged, replaced, or appended. On soapPolling, dataField should point at the array or object that represents emitted records.

MTOM send

Outgoing MTOM uses explicit XOP references. The body must contain the xop:Include element, and the contentId in mtom.attachments must resolve to the same value.

body: |
  <m:UploadDocument xmlns:m="urn:documents">
    <m:DocumentId>{{record.documentId}}</m:DocumentId>
    <m:File>
      <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:{{record.documentId}}"/>
    </m:File>
  </m:UploadDocument>
mtom:
  enabled: true
  attachments:
    - contentId: "{{record.documentId}}"
      contentType: application/pdf
      sourceField: documentBase64
      encoding: base64

encoding: base64 decodes a string field before sending the MIME part. The default, binary, sends string bytes as-is and passes byte arrays through.

Keep the cid: in the XML and the attachment contentId in sync. If one changes without the other, the receiver will see an XOP reference with no matching MIME part.

MTOM receive

When a SOAP response is multipart/related, Cannectors parses the root XML part and exposes MIME attachments on each emitted record under _soapAttachments:

_soapAttachments:
  file-1:
    contentId: file-1
    contentType: application/pdf
    data: <bytes>

Use a mapping or script filter after soapPolling if you want to copy an attachment into a domain-specific field before sending it onward.

WS-Security UsernameToken

wsSecurity supports UsernameToken only: PasswordText and PasswordDigest. It does not implement X.509 certificates, XML signing, or XML encryption.

wsSecurity:
  username: soap-user
  password: ${SOAP_PASSWORD}
  passwordType: PasswordDigest
  mustUnderstand: true

Prefer environment variables or your deployment secret mechanism for passwords. Use PasswordDigest when the SOAP service accepts it; use PasswordText only when the service requires plain-text UsernameToken passwords.

Faults and retries

SOAP faults are surfaced as typed SOAP errors before the module decides whether the pipeline failed, skipped, or logged the record. Retry still follows the module retry block and the HTTP status code returned by the server.

retry:
  maxAttempts: 2
  retryableStatusCodes: [500, 502, 503, 504]

For SOAP outputs, success.statusCodes is evaluated after the SOAP client has accepted the HTTP response. A non-2xx status with no SOAP fault is treated as an HTTP error, so custom SOAP success codes are mainly useful for distinguishing successful 2xx responses.

Known limits

  • No WSDL parsing, code generation, or SOAP/XSD schema validation.
  • No WS-Security signing, encryption, or X.509 support.
  • Unknown fields in SOAP module YAML follow the current project-wide schema behavior and may not be rejected in every nested position.
  • Received MTOM attachments use the _soapAttachments convention until a later version adds a configurable attachment destination.