SOAP is a relic of the 2000s, yet it’s still live in plenty of enterprise stacks. In the last 18 months I migrated the SOAP backend to REST on three different projects: a bank integration, an ERP system, and a government agency API. Each threw up different challenges, but a common pattern settled in.
Here are the practical notes for anyone thinking about the same migration.
SOAP’s real problem
I’m not saying SOAP is a bad protocol technically. XML envelope, WSDL contract, WS-* standards made sense in the enterprise world. The real problem is the current ecosystem:
- Modern clients (mobile, SPA) expect JSON, XML parsing is extra work
- The developer experience is rough: generating stubs from WSDL, namespace collisions, wrestling with SOAP faults
- Observability is poor: hard to debug in Postman, cURL commands run long
- Fewer people know SOAP, which bites you at hiring time
Big bang vs strangler fig
I did a big bang on the first project. Old system off, new system on. I spent a stressful night, the rollback plan was fuzzy, and the next morning three integrations were broken. Lesson learned: on large enterprise systems, big bang doesn’t work.
On the other two projects I used a strangler fig: the new REST API sat in front of the old one as a gateway, clients migrated one by one, and the SOAP endpoint was decommissioned once no consumer was left.
The gateway advantage: it can speak both protocols, acts as a translation layer, and monitoring lets you watch the migration velocity.
Designing the gateway layer
The gateway handles three jobs:
- Protocol translation: REST request comes in, gets wrapped in a SOAP envelope for the backend, the response is converted back to JSON
- Auth bridging: REST uses OAuth 2.0 Bearer, the SOAP backend wants WS-Security, the gateway maps the two
- Routing: the REST endpoint path maps to a SOAP operation
In the enterprise world people reach for Apigee, Kong, or MuleSoft. We solved it with a lightweight NGINX + custom microservice and saved tens of thousands of dollars in license fees a year. At higher volumes you might need to move to a commercial product.
XML to JSON mapping
The sneakiest job is converting the XML envelope to clean JSON. XML has namespaces, attributes, and CDATA sections. JSON expects a flat structure.
Arrays vs objects: in XML a single element uses the same tag as a repeated one, but in JSON you want a single item as an object and multiple items as an array. Your mapping logic has to figure this out automatically.
Attributes: how do XML attributes map to JSON? Pick a convention and stick to it across the whole API. We used an @ prefix for attributes and the plain name for elements.
Date formats: SOAP xsd:dateTime is ISO 8601 without a timezone, the JSON side wants ISO 8601 UTC. You need the conversion.
Error handling differences
SOAP faults and REST status codes live in different worlds:
- SOAP: returns 200 OK with a
<soap:Fault>in the body - REST: 4xx/5xx HTTP status + a JSON error body
The gateway has to parse SOAP faults and map them to the right REST error. We settled on:
FaultCode: Client.Authentication→ 401FaultCode: Client.Authorization→ 403FaultCode: Client.InvalidInput→ 400FaultCode: Server.*→ 500 (logged, client sees a generic message)
Every new FaultCode the backend emits means updating the mapping.
Versioning strategy
During migration the two worlds run side by side. Versioning is non-negotiable:
- SOAP endpoint:
https://api.example.com/soap/v1 - REST endpoint:
https://api.example.com/rest/v1
REST v1 can be a direct mapping of SOAP v1. REST v2 is where you design a cleaner, REST-idiomatic API. Once migration completes, REST v1 gets deprecated.
Consumer coordination
Know who your SOAP consumers are. Which team, which system, how often they call. Run the migration plan in parallel with each consumer.
Deprecation timeline. The SOAP shutdown date has to be announced 6 to 12 months ahead. For the first three months we added a warning response header: X-Deprecated: This endpoint will be removed on YYYY-MM-DD. Some consumers saw it and still did nothing until we reached out directly.
Watch access logs constantly. Who hit the SOAP endpoint in the last 30 days? Expect surprises: offboarded partners, abandoned internal tools, unknown IPs.
As the cutover date nears, start returning 410 Gone, then 503 Service Unavailable, finally 404. A graded shutdown gets consumers to notice. A hard cut blows up your support queue.
Testing: contract tests are non-negotiable
When you write a REST endpoint that preserves the SOAP behaviour, write contract tests for every request type. The semantic equivalence of SOAP response and REST response has to be verified.
Consumer-driven contract tools like Pact help. Each client team writes their expectations, and the gateway verifies those contracts on every build.
The performance bonus
An unexpected win of moving from SOAP to REST was performance. XML parsing is 3 to 5x slower than JSON, the envelope overhead adds about 30% more bytes, and gzip compresses JSON better. Post-migration, p95 latency improved by 25 to 40%.
Final advice
SOAP to REST migration is more an organisational problem than an engineering one. Protocol translation code takes a week, but coordinating 30 consumers, handling auth, monitoring, and regression tracking takes months.
Triple your initial time estimate. All three projects had 6-month estimates and all three landed at 18 months.