Back to blog
Guides & Tutorials

REST vs. SOAP APIs

Learn the real differences between REST, SOAP, and GraphQL APIs with practical code examples, performance metrics, and when to actually use each one.

Saurabh RaiSaurabh Rai

Saurabh Rai

8 min read
REST vs. SOAP APIs

You're building an integration. The third-party vendor hands you their API docs. It's either REST or SOAP, and if you picked wrong in your initial design, you're about to have a bad week.

Here's what actually matters when you're staring at that documentation.

The Real Difference That Matters

REST treats everything as a resource with a URL. You GET a user, POST a new order, DELETE a subscription. It's how the web works, using simple HTTP verbs to do predictable things.

SOAP wraps everything in XML envelopes like it's 2003. Every request is a POST. Every response is wrapped in three layers of XML. Your debugging sessions involve scrolling through angle brackets until you question your career choices.

But here's the thing: sometimes SOAP is the only option. Legacy enterprise systems, banking APIs, and government services often speak SOAP like Workday, Netsuite which are very popular amongst enterprise customers; you either learn their language or find another integration.

Quick Comparison (For Skimmers)

AspectRESTSOAPGraphQL
Payload Size~1KB JSON~5KB XML~2KB JSON
Auth MethodBearer/OAuthWS-SecurityBearer/API Keys
HTTP CachingNative supportNoneComplex
Learning Curve1 day1 week3 days
Error HandlingHTTP status codesSOAP faults in 200 OKField-level errors
Best ForWeb/Mobile appsEnterprise/BankingComplex data needs

REST API Calls: What They Actually Look Like

Getting User Data (The Daily Bread)

GET https://api.example.com/users/123  
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9  
Accept: application/json

Response comes back clean:

{  
  "id": 123,  
  "name": "John Doe",  
  "email": "john@example.com",  
  "created_at": "2025-01-15T10:30:00Z"  
}

No ceremony. No wrapper. Just data.

Creating Resources (When Things Go Right)

POST https://api.example.com/users  
Content-Type: application/json  
Authorization: Bearer token_here
{  
  "name": "Jane Smith",  
  "email": "jane@example.com",  
  "role": "developer"  
}

You get back a 201 Created with the new resource. Status codes tell you what happened. 400? You messed up. 500? They messed up. 401? Your token expired three minutes ago.

Updating (The PATCH vs PUT Debate)

PUT https://api.example.com/users/123  
Content-Type: application/json
{  
  "name": "John Updated",  
  "email": "john.updated@example.com"  
}

PUT replaces the whole resource. PATCH updates just what you send. Most developers misuse PUT, and the difference often goes unnoticed until production data gets accidentally wiped.

SOAP API Calls: The XML Experience

Temperature Conversion (The Classic Example)

POST https://www.w3schools.com/xml/tempconvert.asmx  
Content-Type: text/xml; charset=utf-8  
SOAPAction: "https://www.w3schools.com/xml/CelsiusToFahrenheit"
<?xml version="1.0" encoding="utf-8"?>  
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  
  <soap:Body>  
    <CelsiusToFahrenheit xmlns="https://www.w3schools.com/xml/">  
      <Celsius>25</Celsius>  
    </CelsiusToFahrenheit>  
  </soap:Body>  
</soap:Envelope>

Twenty-five becomes seventy-seven, but only after parsing this response:

<?xml version="1.0" encoding="utf-8"?>  
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  
  <soap:Body>  
    <CelsiusToFahrenheitResponse xmlns="https://www.w3schools.com/xml/">  
      <CelsiusToFahrenheitResult>77</CelsiusToFahrenheitResult>  
    </CelsiusToFahrenheitResponse>  
  </soap:Body>  
</soap:Envelope>

That's 11 lines of XML to convert one number. This is why REST won.

Authentication (Where SOAP Gets Complex)

SOAP's WS-Security standard means your auth looks like this:

<soap:Header>  
  <security:Security xmlns:security="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">  
    <security:UsernameToken>  
      <security:Username>admin</security:Username>  
      <security:Password>password123</security:Password>  
    </security:UsernameToken>  
  </security:Security>  
</soap:Header>

Meanwhile, REST just slaps a Bearer token in the header and calls it a day.

GraphQL: The Third Option You Might Need

POST https://api.example.com/graphql
Content-Type: application/json
{
  "query": "{ user(id: 123) { name email posts { title } } }"
}

One endpoint. Ask for what you need. Get exactly that. No overfetching. No underfetching. Just frontend developers complaining about resolver performance and N+1 queries.

GraphQL shines when:

  • Mobile apps need different data than web
  • You're tired of versioning REST endpoints
  • Frontend teams want independence

GraphQL hurts when:

  • You just need simple CRUD operations
  • Caching becomes a distributed systems problem
  • Junior developers discover nested queries can DDoS your database

Technical Differences That Actually Impact Your Code

Data Format: REST speaks JSON (usually), XML (if you're unlucky), or plain text. SOAP primarily uses XML, though it supports binary attachments via MTOM/XOP for those 50MB PDFs your enterprise client insists on sending. When your JavaScript app needs to consume SOAP, you're parsing XML in the browser like it's 2005.

Error Handling: REST uses HTTP status codes. 404 means not found. Simple. SOAP returns 200 OK even when everything exploded, then makes you parse the XML to find the fault element buried inside. GraphQL? Also 200 OK with errors in the response body. Pattern emerging here.

Performance: REST payloads are smaller. A REST response might be 1KB of JSON. The same SOAP response is 5KB of XML. GraphQL sits in between - more than REST (includes schema), less than SOAP (no envelope overhead). Multiply by thousands of requests. Your bandwidth bill notices.

Security: SOAP has WS-Security baked in with standards for encryption, signatures, and SAML assertions. REST relies on HTTPS and OAuth. GraphQL inherits whatever you implement. SOAP's approach is bulletproof but requires a PhD to implement correctly.

Testing Tools That Actually Work

For Visual People

Postman: The default choice. Handles REST beautifully, struggles with SOAP. Environment variables save your sanity when switching between dev and prod. GraphQL support exists but feels bolted on.

SoapUI: Built for SOAP, tolerates REST. Imports WSDL files and generates all your requests. Ugly interface, powerful features. Ignores GraphQL's existence.

Insomnia: Cleaner than Postman, fewer features. Great for REST, pretends SOAP doesn't exist. Actually good GraphQL support with schema introspection.

Thunder Client: Lives in VS Code. Perfect when you're too lazy to alt-tab.

Bruno: Open source, stores collections as files. Git-friendly. Your team might actually use it.

For Terminal Warriors

curl for REST:

curl -X GET https://api.example.com/users \
  -H "Authorization: Bearer token"

curl for SOAP (yes, it works):

curl -X POST -H "Content-Type: text/xml" \
  -d @soap_request.xml https://api.example.com/soap

curl for GraphQL:

curl -X POST https://api.example.com/graphql \
  -H "Content-Type: application/json" \
  -d '{"query":"{ users { name } }"}'

HTTPie - curl for humans:

http GET api.example.com/users Authorization:"Bearer token"

Libraries That Actually Work

JavaScript/Node.js

For REST: axios or native fetch. Stop overthinking it.

const response = await axios.get('https://api.example.com/users');
// or
const response = await fetch('https://api.example.com/users');

For SOAP: Use strong-soap or soap-typescript in 2025. Callbacks are dead.

import { Client } from 'soap-typescript';
const client = await Client.createClient(wsdlUrl);
const result = await client.MyMethodAsync({param: value});

For GraphQL: Apollo Client if you hate yourself, simple fetch if you don't.

const response = await fetch('/graphql', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ query: '{ users { name } }' })
});

Python

REST: requests. Nothing else matters.

import requests  
response = requests.get('https://api.example.com/users')

SOAP: zeep actually makes it tolerable.

from zeep import Client  
client = Client('https://example.com/service.wsdl')
result = client.service.MyMethod(param='value')

GraphQL: gql or just requests with a string.

query = """{ users { name email } }"""
response = requests.post('/graphql', json={'query': query})

Java

REST: OkHttp for simplicity, Retrofit for type safety. SOAP: JAX-WS is built-in. Apache CXF if you hate yourself. GraphQL: graphql-java if you must.

When to Use What

Use REST when:

  • Building modern web or mobile apps
  • You control both ends
  • Speed and simplicity matter
  • Your team values their sanity
  • HTTP caching can save your bacon

Use SOAP when:

  • Integrating with enterprise systems
  • The bank/government/Fortune 500 requires it
  • You need bulletproof security standards
  • ACID transactions across distributed systems
  • The year is 2003 (or it feels like it)

Use GraphQL when:

  • Multiple clients need different data shapes
  • You're building a product platform
  • Frontend team is sophisticated enough
  • You enjoy debugging resolver performance

Use all three when:

  • You're building an API gateway like Apideck
  • You hate your DevOps team
  • Job security through complexity

Performance Numbers That Matter

Real-world latency breakdown for a user fetch:

  • REST: 50ms network + 10ms processing = 60ms
  • SOAP: 50ms network + 40ms XML parsing = 90ms
  • GraphQL: 50ms network + 20ms resolution = 70ms

Add 10ms for each additional resolver in GraphQL. Add 30ms for each SOAP envelope layer. REST stays flat until you need 15 endpoints for one screen.

The Reality Check

Most developers pick REST. It's simpler, faster, and the documentation makes sense. JSON beats XML. HTTP verbs beat envelope protocols.

But SOAP still runs half the enterprise world. Those banking APIs aren't switching to REST because you tweeted about it. Learn both, use what works, and stop arguing about it on Reddit.

GraphQL? It's great until your junior developer writes a query that joins 17 tables. Then it's a resume-generating event.

The best API is the one that ships your feature. Everything else is noise.

Final Thoughts for Developers

Test your error cases. Half your API calls will fail in production for reasons nobody predicted. That beautiful happy-path code you wrote? It's going to meet network timeouts, malformed responses, and 503 errors at 3 AM.

Version your APIs. Put /v1/ in your URLs. Future you will thank present you when breaking changes become inevitable.

Rate limit everything. That innocent webhook endpoint will get hammered by a misconfigured client sending 10,000 requests per second.

Monitor your p95 latencies, not your averages. Your users experience the worst case, not the mean.

Document your APIs like a developer who has to use them will hunt you down if you don't. Because they will be you, six months from now, wondering what the hell past-you was thinking.

And remember: Apideck's Unify API handles all this complexity so you don't have to. One REST API to rule them all - whether the underlying system is REST, SOAP, or GraphQL. Because life's too short to implement another SOAP client.

Ready to get started?

Scale your integration strategy and deliver the integrations your customers need in record time.

Ready to get started?
Talk to an expert

Trusted by fast-moving product & engineering teams

Nmbrs
Benefex
Invoice2go by BILL
Trengo
Ponto | Isabel Group
Apideck Blog

Insights, guides, and updates from Apideck

Discover company news, API insights, and expert blog posts. Explore practical integration guides and tech articles to make the most of Apideck's platform.

Building Expense Integrations for Microsoft Business Central API
Unified APIGuides & TutorialsAccounting

Building Expense Integrations for Microsoft Business Central API

Master Microsoft Business Central expense API integration with practical examples, authentication setup, and purchase invoice management. Learn how unified APIs can reduce weeks of complex integration work to days.

Saurabh Rai

Saurabh Rai

9 min read
QuickBooks API Pricing and the Intuit App Partner Program
AccountingIndustry insights

QuickBooks API Pricing and the Intuit App Partner Program

If you're planning to build an integration with the QuickBooks Online API, understanding the pricing structure is crucial for budgeting and architectural decisions. While the QuickBooks API was historically free with no volume restrictions, Intuit introduced a significant change in 2025 with the launch of the Intuit App Partner Program.

GJ

GJ

5 min read
Complete Guide to SAP S/4HANA APIs: REST and SOAP Integration Tutorial
Unified APIGuides & Tutorials

Complete Guide to SAP S/4HANA APIs: REST and SOAP Integration Tutorial

Master SAP S/4HANA integration with this complete guide to REST and SOAP APIs. Learn authentication methods, code examples, rate limiting strategies, and when to use OData vs SOAP for enterprise system connectivity.

Saurabh Rai

Saurabh Rai

8 min read