SOAP, WSDL and legacy web services

The envelope and header structure, how a WSDL describes a contract, SOAP faults, the 1.1 versus 1.2 differences, and when a SOAP integration is still the right answer.

The envelope is the whole protocol

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
               xmlns:shop="urn:example:shop">
  <soap:Header>
    <shop:AuthToken soap:mustUnderstand="true">abc123</shop:AuthToken>
  </soap:Header>
  <soap:Body>
    <shop:GetOrder>
      <shop:orderId>1024</shop:orderId>
    </shop:GetOrder>
  </soap:Body>
</soap:Envelope>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Body>
    <soap:Fault>
      <soap:Code>
        <soap:Value>soap:Sender</soap:Value>
        <soap:Subcode><soap:Value>shop:OrderNotFound</soap:Value></soap:Subcode>
      </soap:Code>
      <soap:Reason><soap:Text xml:lang="en">No such order.</soap:Text></soap:Reason>
      <soap:Detail>
        <shop:orderId xmlns:shop="urn:example:shop">1024</shop:orderId>
      </soap:Detail>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>
  • The header carries cross-cutting concerns: authentication, correlation, transaction and routing hints.
  • mustUnderstand="true" means the receiver must process that header or fail; ignoring it is a protocol violation.
  • A SOAP fault is a structured error inside a successful HTTP 500, which is why naive HTTP status handling misses it.
  • SOAP 1.1 uses a different namespace and an faultcode and faultstring shape; the two are not interchangeable.

Reading a WSDL

WSDL elementDescribesMaps to
typesThe XSD schemas used in messagesData model
messageA named set of partsRequest or response payload
portTypeAbstract operationsThe interface (WSDL 2.0 calls it interface)
bindingConcrete protocol and styleSOAP 1.1 or 1.2 over HTTP
serviceEndpoints with addressesThe URL you call
document versus rpcMessage styleDocument is the interoperable choice
literal versus encodedBody encodingLiteral is the interoperable choice
# inspect a WSDL and see the available operations
curl -s "https://service.example.com/OrderService?wsdl" | xmllint --format - | head -60

# call an operation by hand to see the real wire format
curl -s -X POST https://service.example.com/OrderService \
  -H 'Content-Type: application/soap+xml; charset=utf-8' \
  -H 'SOAPAction: "urn:example:shop/GetOrder"' \
  --data-binary @request.xml | xmllint --format -

The interoperable combination is document and literal. The rpc and encoded styles exist for historical reasons and are a common cause of mismatched expectations between toolkits.

When SOAP is still the right answer

  • WS-Security provides message-level signing and encryption that survives intermediaries, which plain HTTPS does not.
  • WS-ReliableMessaging and distributed transactions are specified and implemented, unlike their REST equivalents.
  • Enterprise and government integrations often mandate a WSDL contract and an XSD-validated payload.
  • A machine-readable contract and code generation are genuinely useful when both sides are large organisations that deploy slowly.
  • For a new public API with simple resource semantics, the overhead of the envelope, the contract and the tooling is usually not repaid.
POST /OrderService HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8; action="urn:example:shop/GetOrder"
SOAPAction: "urn:example:shop/GetOrder"

<!-- 1.1 puts the action in the SOAPAction header with quotes;
     1.2 puts it in the content type parameter.
     Sending the wrong one is a frequent interoperability failure. -->
⚠️
Check the HTTP status and the SOAP fault, not one or the other. A service may return HTTP 200 with a fault in the body, or HTTP 500 with no useful body at all, and a client that trusts only the status code will treat a failure as success.

FAQ

Is SOAP dead?
No. It is absent from new consumer APIs and very much alive in enterprise, finance and government integrations where the WS- specifications solve a real problem.
Why do SOAP clients break when the server upgrades?
Usually a schema change in the WSDL types, or a new required header. Version the contract and keep the old endpoint available during the transition.

XML Schema in practice: reuse and evolution XML security: XXE and entity expansion

Last refreshed 2026-09-18.