The same call, twice
Fetching customer 42 from a REST API is a single line and an empty body:
GET /v1/customers/42 HTTP/1.1
Host: api.example.com
Accept: application/json
→ 200 OK
Content-Type: application/json
{ "id": 42, "name": "Ada Lovelace", "country": "GB" }
The same operation against a SOAP 1.1 service looks like this:
POST /CustomerService HTTP/1.1
Host: api.example.com
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://example.com/customers/GetCustomer"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetCustomer xmlns="http://example.com/customers">
<CustomerId>42</CustomerId>
</GetCustomer>
</soap:Body>
</soap:Envelope>
Three things changed. The URL no longer names the customer; it names the service, and every
operation is sent to it. The method is always POST, even for a read. And the operation and
its arguments moved into an XML document, wrapped in an Envelope with a Body
and an optional Header. HTTP has become a pipe; the meaning lives inside the envelope.
Side by side
| SOAP | REST | |
|---|---|---|
| What it is | A protocol, standardised by the W3C | An architectural style, described in Roy Fielding's dissertation |
| Message format | XML only, in an envelope | Any; JSON in practice |
| URLs | One per service | One per resource |
| HTTP method | POST for everything | GET, POST, PUT, PATCH, DELETE by meaning |
| Contract | WSDL, required in practice | OpenAPI, optional |
| Errors | A Fault element in the body | The HTTP status code, plus a body |
| Caching | Not by HTTP caches, since every call is a POST | Built in for GET |
| Security | TLS, plus WS-Security inside the message | TLS, plus a token or key in a header |
| Transport | Usually HTTP; also defined over others such as SMTP and JMS | HTTP |
| Tooling | Code generated from the WSDL | Any HTTP client |
What SOAP gives you
A contract a machine can read
A SOAP service publishes a WSDL file: an XML document listing every operation, the exact type of every argument and result, and the address to send them to. Tools read it and generate a typed client, so calling the service looks like calling a local function and a misspelt field fails at compile time. REST has an equivalent in OpenAPI, but there it is an optional extra that may lag behind the real behaviour; in SOAP the contract is the starting point.
Security and reliability inside the message
The WS-* family of specifications adds features to the envelope's Header. WS-Security can
sign and encrypt individual parts of a message, so it stays protected while it passes through
intermediaries that end the TLS connection, and the signature stays attached to the stored document
afterwards. That is the reason SOAP persists in banking, insurance, healthcare and government
integrations, where a message may need to be proven authentic long after it was sent.
Independence from HTTP
Because nothing in the envelope depends on HTTP, the same message can travel over a message queue or by email. Few new systems need that, but it explains the design: SOAP could not lean on URLs, methods or status codes, so it rebuilt each of them in XML.
What REST gives you
REST gets its features by using HTTP as designed rather than tunnelling through it. A resource's URL is
its identity, so it can be linked, bookmarked and logged meaningfully. GET is safe and
cacheable, so browsers, proxies and CDNs can answer repeat requests without reaching your server. The
status code tells every layer whether the call worked without parsing the body. The
guide to REST APIs covers the constraints in full.
The practical benefits follow. Payloads are small: the JSON response above is a fraction of the size of the equivalent envelope. Any language with an HTTP library can call the API with no generated code. A request can be written by hand, pasted into a terminal as a curl command, or sent from a browser. That low cost of a first call is the main reason public APIs moved to REST.
The cost is looseness. REST is a style, not a standard, so two REST APIs can disagree about pagination,
error bodies, date formats and what PUT does. With SOAP, whatever the service does is at
least written down in one machine-readable place.
Errors are where clients go wrong
A REST API reports failure in the status line: 404 for a missing
customer, 422 for invalid data. A SOAP service reports it in the
body, as a Fault:
HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset=utf-8
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Customer 42 was not found</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
SOAP 1.1 over HTTP sends every fault with status
500, including faults that are the caller's mistake, as
soap:Client says this one is. Monitoring that treats 500 as “the server is broken” will
therefore raise alarms for a mistyped ID. Many services in the wild go further and return
200 with a fault inside. With SOAP, always parse the body before
deciding whether a call succeeded.
SOAP 1.1 and 1.2 differ on the wire
| SOAP 1.1 | SOAP 1.2 | |
|---|---|---|
Content-Type | text/xml | application/soap+xml |
| Operation name | A separate SOAPAction header | An action parameter on Content-Type |
| Envelope namespace | http://schemas.xmlsoap.org/soap/envelope/ | http://www.w3.org/2003/05/soap-envelope |
| Fault fields | faultcode, faultstring | Code, Reason |
Sending a 1.1 envelope with the 1.2 media type, or the reverse, is the most common reason a hand-built
SOAP request is rejected, typically with 415 Unsupported Media
Type or a VersionMismatch fault.
Which to use
| Situation | Choice | Why |
|---|---|---|
| A new public API | REST | Every developer can call it without tooling |
| A mobile or browser client | REST | Small JSON payloads and HTTP caching |
| Integrating with a bank, insurer or tax authority | Whatever they publish, often SOAP | The other side sets the contract |
| Messages that must be signed and kept as records | SOAP with WS-Security | The signature travels with the document |
| An existing SOAP service that works | Leave it | Rewriting a stable integration buys little |
| Screens that need many related objects at once | Consider GraphQL | Neither SOAP nor plain REST was designed for it |
In most projects the choice is made for you: you consume the API that exists. What matters then is recognising which kind you are looking at and applying the right habits to it.
Testing a SOAP endpoint in an HTTP client
A SOAP call is still an HTTP request, so any client can send one. In the
API tester, set the method to POST, enter the service URL,
add a Content-Type header of text/xml; charset=utf-8 for SOAP 1.1 and a
SOAPAction header with the value from the WSDL, quotes included, then paste the envelope
into the body. Run the response through the XML formatter to make it
readable, and look for a Fault element whatever the status code says.
From a terminal the same request is a curl command with an XML body. If the service answers 415, check the Content-Type against the SOAP version; if it answers 500, read the fault before assuming the server is at fault.
References
- W3C: SOAP Version 1.2 Part 1 — The messaging framework: envelope, header, body and fault.
- W3C Note: SOAP 1.1 — The earlier version, including the SOAPAction header and the rule that faults use HTTP 500.
- W3C Note: WSDL 1.1 — The service description language most SOAP services publish.
- Fielding: Representational State Transfer — Chapter 5 of the dissertation that defined REST.
These links leave api-tester.com, which is independent of the organisations they point to.
Frequently asked questions
What is the main difference between SOAP and REST?
SOAP is a protocol with a fixed XML envelope, in which every call is a POST to one service URL and the operation is named inside the message. REST is a style of using HTTP directly: each resource has its own URL, and the HTTP method and status code carry the meaning.
Is SOAP still used?
Yes, widely, in banking, insurance, healthcare, telecoms and government systems. New public APIs are rarely built with it, but a great many existing integrations depend on it and are not being replaced.
Is REST faster than SOAP?
Usually. JSON payloads are smaller than XML envelopes and cheaper to parse, and REST reads can be served from HTTP caches while SOAP calls cannot, because they are all POST requests. For a single uncached call the network round trip dominates and the difference is small.
Can SOAP use JSON?
No. The SOAP specification defines the envelope as XML. An API that accepts JSON is not SOAP, although some gateways translate between a JSON front end and a SOAP back end.
Is SOAP more secure than REST?
Not by default. Both normally rely on TLS. SOAP additionally has WS-Security, which signs and encrypts parts of the message itself, so protection survives intermediaries and storage. REST has no single equivalent standard, and most REST APIs do not need one.
Can I test a SOAP API with a REST client?
Yes. Send a POST to the service URL with the XML envelope as the body, the Content-Type the SOAP version expects, and for SOAP 1.1 a SOAPAction header. Then read the response body for a Fault element, since a failed call may still arrive with status 200 or 500.