SOAP in the enterprise: ESBs, gateways and middleware
In large organisations SOAP rarely reaches the service directly. Knowing what the gateway does explains most production-only failures.
What the middleware does
| Function | Benefit | Failure mode |
|---|---|---|
| TLS termination | One place for certificates | Message-level signatures still need to verify end to end |
| Authentication | Central policy, single audit trail | The service sees an anonymous caller and cannot authorise finely |
| Routing and versioning | Old and new endpoints coexist | Path rewriting breaks wsa:To and SOAPAction |
| Transformation | Bridging two contracts | Silent field loss that only appears in reconciliation |
| Throttling | Protecting the backend | 429 or a generic fault the client does not classify correctly |
| Message logging | Traceability for regulated industries | Payloads with personal data stored in plain text |
| Store and forward | Buffering when the backend is down | Duplicate delivery when the client also retries |
<!-- 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># 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.xmlWorking with the gateway team
- Get the exact modified request the backend receives. A gateway that rewrites the action or strips the namespace is invisible from the client side.
- Agree on correlation: one identifier that survives the gateway and appears in both logs, so a ticket can be traced end to end.
- Ask whether the gateway retries. If it does, the backend must be idempotent, and a duplicate on the business side is a gateway artefact, not a client bug.
- Check the timeout budget at each hop. If the client waits 30 seconds and three hops each wait 30 seconds, the effective timeout is whatever the slowest path allows.
- For a version migration, run both endpoints behind one gateway hostname and route by path or by action, so consumers change only their configuration.
- Log request identifiers, not payloads, by default. When payload logging is required for compliance, redact and set a retention period.
💡
Set the client timeout shorter than the gateway's, and the gateway's shorter than the backend's. When the outermost timeout fires first, the client reports a timeout while the backend is still working — and the caller has no way to learn the outcome.
FAQ
Should our service trust the gateway's authentication?
Only with a mechanism that makes the claim verifiable, such as a signed token or mutual TLS on the internal hop. A plain header asserting a username is trivially forged by anything that can reach the backend.
How do we version a contract at the gateway?
Add a new endpoint path or a new service element and route it explicitly. Editing the existing entry in place means a rollback is the only recovery, which is exactly what you want to avoid.
Related
Building a SOAP service: contract-first and code-first WS-Security: authentication, signing and encryption
Last refreshed 2026-09-18.