SOAP cheat sheet

A scannable SOAP reference: 10 short snippets across 7 topics, each linking back to the lesson it came from.

At a glance

TopicWhat it covers
WSDL contracts and code generationGenerated code turns the contract into classes and a proxy whose methods look like local calls. The WSDL becomes yourlesson
Calling a SOAP service, and why REST usually winsREST wins for new work because it leans on what HTTP already gives you — methods, status codes, caching, proxies — andlesson
SOAP 1.1 versus 1.2 and HTTP bindingsThe two versions differ in namespace, content type and how faults travel over HTTP, and a client that guesses wronglesson
Building a SOAP service: contract-first and code-firstThe direction you choose is really a decision about where the review of the interface happens. Contract-first puts itlesson
Attachments and binary data: MTOM and SwABase64 inside the envelope is simple and wasteful. MTOM keeps the XML readable and sends the bytes as raw binarylesson
Interoperability between .NET, Java and legacy stacksMost cross-vendor failures come from a handful of known divergences in encoding, dates, nulls and empty collectionslesson
SOAP in the enterprise: ESBs, gateways and middlewareIn large organisations SOAP rarely reaches the service directly. Knowing what the gateway does explains mostlesson

Quick snippets

WSDL contracts and code generation

Generating a client

# Java: JDK ships wsimport; Jakarta's wsdl2java is the maintained option
wsimport -keep -p com.example.quotes -d out https://api.example.com/quotes?wsdl
wsdl2java -d out -p com.example.quotes https://api.example.com/quotes?wsdl

# .NET
dotnet svcutil https://api.example.com/quotes?wsdl

# Python: ask for a plain dictionary instead of a proxy class
python -m zeep https://api.example.com/quotes?wsdl

Full lesson: WSDL contracts and code generation →

Calling a SOAP service, and why REST usually wins

The call on the wire

curl -sS https://api.example.com/quotes \
  -H 'Content-Type: text/xml; charset=utf-8' \
  -H 'SOAPAction: "urn:example:quotes/GetQuote"' \
  --data-binary @request.xml

Full lesson: Calling a SOAP service, and why REST usually wins →

SOAP 1.1 versus 1.2 and HTTP bindings

What actually differs

POST /OrderService HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:example:orders/PlaceOrder"

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <PlaceOrder xmlns="urn:example:orders"><sku>A-1</sku><qty>2</qty></PlaceOrder>
  </soap:Body>
</soap:Envelope>

What actually differs

POST /OrderService HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8; action="urn:example:orders/PlaceOrder"

<?xml version="1.0"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
  <env:Body>
    <PlaceOrder xmlns="urn:example:orders"><sku>A-1</sku><qty>2</qty></PlaceOrder>
  </env:Body>
</env:Envelope>

Full lesson: SOAP 1.1 versus 1.2 and HTTP bindings →

Building a SOAP service: contract-first and code-first

The mechanics of each direction

# Contract-first with JAX-WS: generate the portable artifacts, then implement
wsimport -keep -p com.example.orders -d build/classes contract.wsdl

# .NET: generate a client or a server-side abstract class
dotnet tool install --global dotnet-svcutil
dotnet-svcutil contract.wsdl --outputDir Generated

# Java: publish a contract-first endpoint without a container
# (endpoint is the portable JAX-WS API)
#   Endpoint.publish("http://0.0.0.0:8080/orders", new OrderServiceImpl());
# then check it
curl -s "http://localhost:8080/orders?wsdl" | head -20

Full lesson: Building a SOAP service: contract-first and code-first →

Attachments and binary data: MTOM and SwA

Three ways to send bytes

Content-Type: multipart/related; type="application/xop+xml";
              start="<[email protected]>"; start-info="application/soap+xml";
              boundary="MIME_boundary"

Practical rules

// Enable MTOM on a WCF-style binding and stream the body
var binding = new BasicHttpBinding
{
    MessageEncoding = WSMessageEncoding.Mtom,
    TransferMode = TransferMode.Streamed,
    MaxReceivedMessageSize = 64L * 1024 * 1024,
    ReaderQuotas = { MaxArrayLength = 64 * 1024 * 1024 }
};
// TransferMode.Streamed matters more than the size limits:
// it keeps the payload off the managed heap.

Full lesson: Attachments and binary data: MTOM and SwA →

Interoperability between .NET, Java and legacy stacks

The known divergences

# Normalise both responses and diff them
xsltproc tools/compare.xsl java-response.xml > java.txt
xsltproc tools/compare.xsl dotnet-response.xml > dotnet.txt
diff -u java.txt dotnet.txt

Full lesson: Interoperability between .NET, Java and legacy stacks →

SOAP in the enterprise: ESBs, gateways and middleware

What the middleware does

<!-- A gateway-added header you should expect and tolerate -->
<soap:Header>
  <gw:RoutingId xmlns:gw="urn:example:gateway">abc-123</gw:RoutingId>
  <gw:ReceivedAt xmlns:gw="urn:example:gateway">2026-09-18T10:00:03Z</gw:ReceivedAt>
  <wsse:Security><!-- the gateway may replace the original token --></wsse:Security>
</soap:Header>

What the middleware does

# Prove where a failure happens: measure the gap between hops
curl -s -o /dev/null -w 'gateway connect=%{time_connect} total=%{time_total}\n' \
  -X POST https://gateway.example.com/orders --data-binary @req.xml

curl -s -o /dev/null -w 'direct   connect=%{time_connect} total=%{time_total}\n' \
  -X POST https://orders.internal/OrderService --data-binary @req.xml

Full lesson: SOAP in the enterprise: ESBs, gateways and middleware →

FAQ

Is this SOAP cheat sheet free to use?
Yes. No sign-up and no tracking: the page is static, every example is on the page itself, and you can print it or save it as a one-page reference.
Where do the examples come from?
Every snippet is taken from the 7 lessons of the SOAP course on this site, and each section links back to the lesson it was pulled from.
How do I go deeper than a cheat sheet?
Open the full SOAP course — it carries the worked explanations, the edge cases and the exercises behind every line here.

XML XPath XSLT RESTful APIs RSS & Atom

Last refreshed 2026-09-27.