Toolmingo
Guides10 min read

REST vs SOAP: Which API Style Should You Use in 2025?

In-depth REST vs SOAP comparison: architecture, performance, security, when to use each, and real-world examples with code.

REST and SOAP are two approaches for building web APIs. REST dominates modern development, but SOAP still powers millions of enterprise integrations. This guide explains every meaningful difference with examples.

At a Glance

Dimension REST SOAP
Full name Representational State Transfer Simple Object Access Protocol
Protocol Architectural style (HTTP) Protocol (HTTP, SMTP, TCP, …)
Message format JSON, XML, HTML, plain text XML only
WSDL/contract Optional (OpenAPI) Required (WSDL)
Statefulness Stateless Stateful or stateless
Standards Loose (HTTP verbs + URLs) Strict (WS-* specs)
Error handling HTTP status codes Fault element in envelope
Built-in security HTTPS (+ OAuth, JWT) WS-Security
Performance Fast (lightweight payloads) Slower (verbose XML)
Tooling Postman, curl, any HTTP client WSDL-aware tools (SoapUI)
Best for Web/mobile APIs, microservices Enterprise, banking, legacy

What Is REST?

REST (Representational State Transfer) is an architectural style defined by Roy Fielding in 2000. It uses HTTP as the transport and has six constraints:

  1. Client–server — UI and data storage are separated
  2. Stateless — each request contains all context; no session state on server
  3. Cacheable — responses declare whether they can be cached
  4. Uniform interface — resources identified by URLs, manipulated via representations
  5. Layered system — client doesn't know if it's talking to origin or proxy
  6. Code on demand (optional) — server can send executable code (e.g., JavaScript)

REST Request Example

GET /users/42 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGci...
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 42,
  "name": "Ana Kovač",
  "email": "ana@example.com"
}

REST CRUD Mapping

Operation HTTP Method URL Status Code
Create POST /users 201 Created
Read (list) GET /users 200 OK
Read (single) GET /users/42 200 OK
Update (full) PUT /users/42 200 OK
Update (partial) PATCH /users/42 200 OK
Delete DELETE /users/42 204 No Content

What Is SOAP?

SOAP (Simple Object Access Protocol) is a protocol with a strict XML envelope structure. It was designed for enterprise systems requiring formal contracts, built-in transactions, and advanced security.

SOAP Message Structure

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:usr="http://example.com/users">

  <soapenv:Header>
    <wsse:Security>
      <!-- WS-Security token here -->
    </wsse:Security>
  </soapenv:Header>

  <soapenv:Body>
    <usr:GetUserRequest>
      <usr:UserId>42</usr:UserId>
    </usr:GetUserRequest>
  </soapenv:Body>

</soapenv:Envelope>

SOAP Response

<soapenv:Envelope ...>
  <soapenv:Body>
    <usr:GetUserResponse>
      <usr:Id>42</usr:Id>
      <usr:Name>Ana Kovač</usr:Name>
      <usr:Email>ana@example.com</usr:Email>
    </usr:GetUserResponse>
  </soapenv:Body>
</soapenv:Envelope>

SOAP Fault (Error Response)

<soapenv:Body>
  <soapenv:Fault>
    <faultcode>soapenv:Client</faultcode>
    <faultstring>User not found: 42</faultstring>
    <detail>
      <usr:ErrorCode>USER_NOT_FOUND</usr:ErrorCode>
    </detail>
  </soapenv:Fault>
</soapenv:Body>

WSDL vs OpenAPI

SOAP requires a WSDL (Web Services Description Language) contract. REST typically uses OpenAPI (formerly Swagger), though it's optional.

Feature WSDL (SOAP) OpenAPI (REST)
Format XML YAML or JSON
Required Yes No (optional)
Code gen Auto-generates client stubs Auto-generates client SDKs
Discovery ?wsdl endpoint /openapi.json or /docs
Tooling SoapUI, wsdl2java Swagger UI, Postman, Redoc
Human-readable Verbose, hard to read Readable YAML

WSDL snippet:

<wsdl:operation name="GetUser">
  <wsdl:input message="tns:GetUserRequest"/>
  <wsdl:output message="tns:GetUserResponse"/>
</wsdl:operation>

OpenAPI equivalent:

/users/{id}:
  get:
    summary: Get user by ID
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
    responses:
      '200':
        description: User found
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'

Security Comparison

Security Aspect REST SOAP
Transport security TLS/HTTPS TLS/HTTPS
Message-level security Manual (JWE, application layer) WS-Security (built into protocol)
Authentication OAuth 2.0, JWT, API keys, Basic WS-Security UsernameToken, SAML
Authorization Custom (JWT claims, scopes) XACML, WS-Trust
Integrity HTTPS + HMAC signatures XML Digital Signature
Non-repudiation Hard to guarantee WS-Security provides this
End-to-end encryption HTTPS only (TLS terminates at proxy) XML Encryption (survives routing)

Key SOAP security advantage: WS-Security provides message-level security — the payload stays encrypted even if it passes through intermediaries (message brokers, ESBs). REST's HTTPS only protects the transport channel.

<!-- WS-Security header example -->
<wsse:Security>
  <wsse:UsernameToken>
    <wsse:Username>api-user</wsse:Username>
    <wsse:Password Type="PasswordDigest">dGVzdA==</wsse:Password>
    <wsse:Nonce>abc123</wsse:Nonce>
    <wsu:Created>2025-07-16T10:00:00Z</wsu:Created>
  </wsse:UsernameToken>
</wsse:Security>

Performance Comparison

REST is generally faster because:

  1. Smaller payloads — JSON is ~30–50% smaller than equivalent XML
  2. HTTP caching — GET responses can be cached by browsers, CDNs, proxies
  3. Less parsing overhead — JSON parsing is faster than XML DOM parsing
  4. No envelope overhead — no mandatory header/body wrapping
# Payload size comparison (same user object)

# REST JSON: 68 bytes
{"id": 42, "name": "Ana Kovač", "email": "ana@example.com"}

# SOAP XML: ~450 bytes (with envelope)
# <?xml version="1.0"?><soapenv:Envelope ...><soapenv:Body>
# <GetUserResponse><Id>42</Id><Name>Ana Kovač</Name>
# <Email>ana@example.com</Email></GetUserResponse>
# </soapenv:Body></soapenv:Envelope>

Caveat: Performance difference matters less at the network layer for large payloads. CPU cost of XML validation and signing is the bigger SOAP bottleneck.


Code Examples: Calling Both APIs

Calling a REST API (Python)

import httpx

# GET user
response = httpx.get(
    "https://api.example.com/users/42",
    headers={"Authorization": "Bearer eyJhbGci..."}
)
user = response.json()
print(user["name"])  # Ana Kovač

# POST create user
new_user = httpx.post(
    "https://api.example.com/users",
    json={"name": "Marko", "email": "marko@example.com"},
    headers={"Authorization": "Bearer eyJhbGci..."}
)
print(new_user.status_code)  # 201

Calling a SOAP API (Python with zeep)

from zeep import Client
from zeep.wsse.username import UsernameToken

client = Client(
    wsdl="https://api.example.com/UserService?wsdl",
    wsse=UsernameToken("api-user", "secret", use_digest=True)
)

# Call GetUser operation
response = client.service.GetUser(UserId=42)
print(response.Name)  # Ana Kovač

# Call CreateUser operation
result = client.service.CreateUser(
    Name="Marko",
    Email="marko@example.com"
)
print(result.Success)  # True

Calling a SOAP API (Java with JAX-WS)

// Auto-generated stub from WSDL (wsimport or wsdl2java)
UserService service = new UserService();
UserPortType port = service.getUserPort();

// Set WS-Security credentials
BindingProvider bp = (BindingProvider) port;
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "api-user");
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "secret");

GetUserRequest request = new GetUserRequest();
request.setUserId(42);

GetUserResponse response = port.getUser(request);
System.out.println(response.getName()); // Ana Kovač

WS-* Standards (SOAP Extensions)

SOAP has an ecosystem of WS-* (Web Services) specifications:

Standard Purpose
WS-Security Message-level auth, encryption, signing
WS-ReliableMessaging Guaranteed message delivery
WS-AtomicTransaction Distributed ACID transactions
WS-Addressing Endpoint routing, async reply-to
WS-Policy Machine-readable service capabilities
WS-Trust Token issuance (STS)
WS-Federation Identity federation across domains
WS-BPEL Business process orchestration

REST has no equivalent built-in standards — you implement these at the application layer.


Where REST Wins

Scenario Why REST
Public APIs (Twitter, GitHub, Stripe) Simple HTTP, any client language
Mobile and web apps Low payload = faster on mobile networks
Microservices Lightweight, easy to deploy, HTTP-native
Developer experience Easy to test with curl, Postman, browser
Caching HTTP GET responses cache natively
Serverless / edge functions No heavy SOAP client library needed
Rapid prototyping No WSDL to write before coding
JavaScript frontends JSON parses natively

Where SOAP Wins

Scenario Why SOAP
Banking / financial systems WS-Security, non-repudiation, atomicity
Healthcare (HL7, HIPAA) Required audit trail, WS-ReliableMessaging
Enterprise ERP/SAP integration SAP SOAP APIs are standard
Distributed transactions WS-AtomicTransaction across services
Message-level encryption Payload encrypted through intermediaries
Formal contracts required WSDL forces strict API contract upfront
Legacy system integration Existing SOAP services everywhere
Government/regulated industries Compliance often mandates SOAP

Full Comparison Table

Feature REST SOAP
Protocol HTTP (style) HTTP, SMTP, TCP, others
Message format JSON, XML, text XML only
Contract Optional (OpenAPI) Required (WSDL)
Statefulness Stateless Can be stateful
Standards Informal WS-* formal specs
Security HTTPS + app-layer WS-Security (protocol-level)
Transactions None built-in WS-AtomicTransaction
Reliable messaging None built-in WS-ReliableMessaging
Caching HTTP caching Not supported
Payload size Small (JSON) Large (XML + envelope)
Performance Higher Lower
Learning curve Low High
Tooling Any HTTP client WSDL-aware clients
Code generation OpenAPI generators wsdl2java, wsimport
Error handling HTTP status codes SOAP Fault XML
Versioning URL (/v1, /v2) or headers WSDL namespace
Browser support Native Requires SOAP client library
Adoption (new projects) ~95% ~5%
Legacy systems Rare Common

REST vs SOAP vs GraphQL vs gRPC

REST SOAP GraphQL gRPC
Protocol HTTP HTTP/XML HTTP HTTP/2 + Protobuf
Format JSON XML JSON Binary
Contract OpenAPI WSDL Schema .proto file
Query flexibility Fixed endpoints Fixed operations Flexible queries Fixed methods
Streaming No (SSE workaround) No Subscriptions Bidirectional
Performance Good Slow Medium Excellent
Best for Public APIs Enterprise/legacy Complex frontends Microservices
Browser native Yes No Yes No (grpc-web)
Learning curve Low High Medium Medium

Decision Guide

Need to integrate with existing SOAP/WSDL system?
→ SOAP

Need distributed transactions across services?
→ SOAP (WS-AtomicTransaction)

Building a public API (web or mobile)?
→ REST

Building a microservices backend?
→ REST or gRPC

Frontend needs flexible data fetching?
→ GraphQL

Performance-critical internal services?
→ gRPC

Everything else?
→ REST

Migrating from SOAP to REST

If you're modernizing a SOAP service, a common approach is the anti-corruption layer pattern:

# REST façade in front of legacy SOAP service
from fastapi import FastAPI
from zeep import Client

app = FastAPI()
soap_client = Client(wsdl="https://legacy.example.com/UserService?wsdl")

@app.get("/users/{user_id}")
def get_user(user_id: int):
    # Translate REST request to SOAP call
    soap_response = soap_client.service.GetUser(UserId=user_id)
    
    # Translate SOAP response to REST JSON
    return {
        "id": user_id,
        "name": soap_response.Name,
        "email": soap_response.Email
    }

This lets new clients use REST while the SOAP backend stays unchanged.


Common Mistakes

Mistake REST SOAP
Wrong HTTP verb Using POST for reads
Ignoring status codes Always returning 200
Not versioning API Breaking clients on change
Skipping WS-Security Sending sensitive data unencrypted
Parsing WSDL manually Always use code generation
No caching headers Losing performance gains
Treating REST as CRUD only Missing resource modeling
SOAP for public API Poor developer experience

REST vs SOAP vs Related Terms

Term Relationship to REST/SOAP
HTTP Transport protocol REST is built on
JSON Most common REST response format
XML Required SOAP format; optional in REST
OpenAPI / Swagger REST API documentation standard
WSDL SOAP API contract format
GraphQL Alternative to REST for query flexibility
gRPC Alternative to REST for performance
ESB Enterprise Service Bus — routes SOAP messages
SOA Service-Oriented Architecture — SOAP ecosystem
Microservices Modern architecture style; uses REST/gRPC
API Gateway Sits in front of REST APIs (Kong, AWS API GW)

FAQ

Q: Is SOAP dead?
No. Millions of SOAP services run in banking, healthcare, government, and enterprise ERP systems. New development rarely chooses SOAP, but existing SOAP integrations will run for decades.

Q: Can REST be as secure as SOAP?
Yes, with HTTPS + OAuth 2.0 + JWT + proper implementation, REST is secure for most use cases. SOAP's WS-Security advantage matters when you need message-level encryption that survives intermediaries, which is rare outside highly regulated industries.

Q: Which is faster: REST or SOAP?
REST is typically 30–50% faster in practice because JSON payloads are smaller and cheaper to parse than XML. The difference matters most at high request volumes (millions/day).

Q: Does REST require JSON?
No. REST can use XML, HTML, plain text, or any format. JSON is used because it's lightweight and JavaScript-native, not because REST requires it.

Q: Can SOAP use HTTP GET?
Technically yes, but SOAP almost always uses HTTP POST because the entire request is in the XML body. There's no concept of URL-based resources.

Q: Should I learn SOAP in 2025?
Learn REST first — you'll use it in almost every job. Learn SOAP only if you work in finance, healthcare, enterprise integration, or need to maintain legacy systems. Basic SOAP knowledge is useful; deep WS-* expertise is only needed for specialist roles.

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools