API Facade Patterns for Legacy Carrier Integration: Bridging SOAP and REST Without Breaking Multi-Tenant Isolation

API Facade Patterns for Legacy Carrier Integration: Bridging SOAP and REST Without Breaking Multi-Tenant Isolation

Modern carrier APIs are undergoing a massive transformation. UPS was the first to phase out its legacy APIs in 2025, while USPS began gradually transitioning out older APIs and replacing them with OAuth-secured, RESTful APIs. Carrier API changes from UPS, USPS, and FedEx are coming in 2026. USPS has announced their current Web Tools API platform will retire on January 25, 2026, following similar moves by their competitors.

This isn't just about keeping up with modern security standards. Legacy systems create genuine bottlenecks. Shipping expectations have changed, and legacy API systems struggled to keep up. Older APIs relied on static service standards, approximate pricing logic, and multiple calls to handle a single shipment. Upgraded APIs return more precise delivery dates, handle pricing logic more accurately, and surface address issues earlier.

If you're building carrier integration software that needs to bridge these worlds while maintaining multi-tenant isolation, the API facade pattern provides the translation layer you need.

Why Legacy Carrier APIs Create Integration Nightmares

The scope of change isn't trivial. FedEx ended SOAP support on May 15, 2024, followed by UPS on June 3, 2024. UPS is retiring its SOAP-based APIs and moving to RESTful APIs. All integrations must switch to REST APIs before this date to avoid service interruptions.

For carriers, the move makes sense. Both carriers are moving to a RESTful API using a more advanced security model like OAuth 2.0 instead of single access key authentication. Shippers who are using older protocols like XML or SOAP for their API integrations will have to make a conversion to something that's RESTful compatible.

But for middleware platforms like Cargoson, ShipEngine, nShift, and MercuryGate, this creates a complex bridging problem. You can't simply shut off legacy support overnight when hundreds of clients depend on it. You need a way to expose modern interfaces while seamlessly translating to whatever backend systems your carrier integrations require.

The challenge extends beyond protocol translation. Multi-tenant platforms face additional complexity: tenant A might be ready for OAuth 2.0 and REST, while tenant B still needs SOAP support for their legacy ERP system. Your facade needs to handle both without compromising isolation or performance.

The API Facade Pattern: Your Translation Layer

The API facade pattern creates a buffer between what your clients see and what your backend integrations actually do. We can use the Facade Pattern to simplify a library's interface to only the subset we require. Instead of directly integrating dependencies using each library's API, we can write business logic in the language of our problem domain. Our clients do not need to know about the underlying implementation of the integration.

In carrier integration middleware, this translates to a clean separation of concerns:

  • Northbound Interface: Modern REST APIs with consistent schemas, OAuth 2.0 authentication, and standardised error handling
  • Southbound Integration: Whatever the carrier actually provides - SOAP, REST, XML over HTTP, or proprietary protocols
  • Translation Layer: The facade that converts between these worlds

Your facade exposes endpoints like POST /api/v1/shipments regardless of whether you're talking to UPS's new REST API or FedEx's legacy SOAP service behind the scenes. Clients get consistency while you handle the complexity internally.

Multi-Tenant Facade Architecture Design

Multi-tenancy adds layers of complexity that go beyond simple API translation. Multi-tenancy is one of those architectural challenges that looks simple on paper — "just add a tenant ID to the request" — but quickly explodes into complexity when you need real isolation, routing, and observability at scale. An API Gateway often becomes the front line in solving this problem. Beyond just rate-limiting or authentication, the gateway can enforce multi-tenant request routing, ensuring each tenant's traffic is handled according to the right rules.

Your facade needs to handle tenant identification, routing, and isolation without breaking the abstraction. The most common approaches for tenant identification include:

The API is designed in a way to mandatorily accommodate tenant-id as part of the URL path. So that the server can parse the URL path to get the tenant-id. Most of the multitenant system uses this approach to identify their tenant context. Routes like /api/tenant-alpha/shipments make tenant boundaries explicit and allow for tenant-specific configurations.

Subdomain-based identification offers cleaner URLs but requires additional DNS management. Your application is accessed by your client via their own subdomain. This approach the server requires an additional effort to maintain the mapping between the tenant's domain and tenant id from your end.

Your facade must also handle tenant-specific configurations. Tenant A might have negotiated rates with FedEx requiring custom rate shopping logic, while Tenant B needs to route international shipments through DHL. API Management supports named values, which are custom configuration settings that you can use throughout your policies. For example, you might use a named value to store a tenant's back-end URL and then reuse that same value in several places within your policies. In a multitenant solution, it's important to be careful when you set the names of your named values. If the settings vary between tenants, make sure to include the tenant identifier in the name.

Protocol Translation Strategies

The core challenge is converting between different protocol paradigms while maintaining consistency. REST and SOAP have fundamentally different approaches to data structure and error handling.

For SOAP-to-REST translation, you'll typically need to:

  • Convert XML payloads to JSON while preserving semantic meaning
  • Map SOAP fault codes to HTTP status codes
  • Handle SOAP's strict schema validation vs REST's flexible data structures
  • Transform SOAP's action-based approach to REST's resource-based model

Consider a UPS address validation request. The legacy SOAP version requires a complex XML envelope with multiple nested elements. Your facade can expose a simple REST endpoint:

POST /api/v1/addresses/validate
{
  "street": "123 Main St",
  "city": "Atlanta",
  "state": "GA",
  "postal_code": "30309",
  "country": "US"
}

Behind the scenes, your facade transforms this into the required SOAP envelope, handles the XML parsing, and returns a clean JSON response with standardised error codes.

Authentication translation is equally important. Both carriers are moving to a RESTful API using a more advanced security model like OAuth 2.0 instead of single access key authentication. Your facade might accept OAuth 2.0 tokens from clients while managing legacy API keys or SOAP security headers for backend services.

Resilience Patterns for Facade Implementations

Legacy systems often lack modern resilience features, making your facade the critical layer for protecting both upstream clients and downstream services. Loose coupling, such as by using messaging approaches, can provide a range of benefits for security, performance isolation, and resiliency. When possible, you should loosely couple your integrations with external systems. If you need to tightly couple to an external system, ensure that you follow good practices like the Retry pattern, the Circuit Breaker pattern, and the Bulkhead pattern.

Circuit breakers become especially important when dealing with carrier APIs that might have unpredictable availability. If FedEx's SOAP service starts timing out, your circuit breaker can fail fast and potentially route shipments through alternative carriers rather than cascading failures to your clients.

Rate limiting protects legacy systems that weren't designed for modern traffic volumes. A 1990s-era SOAP service might handle 10 requests per second gracefully but fail catastrophically at 100 requests per second. Your facade can implement intelligent throttling that backs off when error rates increase.

Implementing retry logic with exponential backoff helps handle the intermittent connectivity issues common with legacy systems. However, be careful with carrier APIs that process financial transactions - you don't want to accidentally create duplicate shipments because of aggressive retry policies.

Implementation Strategies and Deployment Patterns

Building your facade incrementally reduces risk and allows for gradual migration. Start with high-value, low-complexity operations like address validation or rate shopping before tackling complex workflows like international customs documentation.

Containerisation offers significant advantages for facade deployment. Each tenant's specific protocol requirements can be isolated in separate containers while sharing the common facade framework. This approach works well with platforms like Kubernetes where you can dynamically scale tenant-specific processing based on demand.

Consider using service mesh patterns for inter-service communication. If your facade needs to coordinate with inventory management systems, order management platforms, or billing services, a service mesh provides the observability and control you need for complex multi-tenant routing.

Feature flags become crucial during migration periods. You can expose both legacy and modern endpoints simultaneously, allowing tenants to migrate at their own pace. We can change the implementation of the integration and our clients wouldn't know as long as the interface stayed the same.

Database schema considerations matter for multi-tenant facades. Tenant-specific configurations, carrier credentials, and routing rules need secure storage with proper isolation. Consider using tenant-prefixed naming patterns for configuration keys to prevent cross-tenant data leakage.

Operational Monitoring and Governance

Observability becomes more complex when your facade bridges multiple protocols and serves multiple tenants. You need visibility into both the external API contracts and internal translation processes.

Distributed tracing is essential for understanding request flows that span REST-to-SOAP translation, multiple carrier APIs, and tenant-specific routing logic. Each trace should include tenant context, selected carrier, protocol translation markers, and performance metrics for both inbound and outbound calls.

API Management has a powerful cache feature that you can use to cache entire HTTP responses or any other data. For example, you can use the cache for tenant mappings if you use custom logic or if you look up the mapping from an external service. Use the cache-store-value and cache-lookup-value policies to implement a caching approach. However, in a multitenant solution, it's important to be careful when you set your cache keys. If the cached data might vary between tenants, ensure that you include the tenant identifier in the cache key. Include the identifier to reduce the chance of accidentally referring to or being manipulated into referring to another tenant's value when you process a request for another tenant.

Establish SLOs that account for the complexity of your translation layer. A facade calling three different carrier APIs to fulfil a single rate shopping request has different performance characteristics than a simple passthrough proxy. Your SLOs should reflect the compound latency and availability requirements.

Security monitoring requires attention to both modern OAuth 2.0 flows and legacy authentication mechanisms. Log authentication attempts, token validations, and any suspicious patterns in tenant access. Legacy SOAP services often provide limited security logging, making your facade the primary audit point.

The API facade pattern isn't just about technical translation - it's about creating the foundation for reliable, scalable carrier integration that can evolve with changing requirements while maintaining the isolation and performance your tenants depend on.

Read more

Atomic Rate Limiting Coordination for Multi-Tenant Carrier Integration: Redis Lua Patterns That Prevent Race Conditions Without Breaking Tenant Isolation

Atomic Rate Limiting Coordination for Multi-Tenant Carrier Integration: Redis Lua Patterns That Prevent Race Conditions Without Breaking Tenant Isolation

Multi-tenant carrier integration platforms face a coordination nightmare when multiple gateway instances need atomic rate limiting across service boundaries. Any multitenant service with public REST APIs needs to be able to protect itself from excessive usage by one or more tenants, and as the number of instances that support these

By Koen M. Vermeulen
Multi-Tenant Carrier Integration Migration to HTTP/3: Solving Connection Pooling and Observability Challenges Without Breaking Tenant Isolation

Multi-Tenant Carrier Integration Migration to HTTP/3: Solving Connection Pooling and Observability Challenges Without Breaking Tenant Isolation

DHL's APIs now support HTTP/3. FedEx has experimental QUIC endpoints running. UPS is evaluating QUIC for their tracking services. Your multi-tenant carrier integration middleware, serving 500+ shippers, suddenly faces a migration challenge that goes deeper than switching protocols. Traditional carrier integration middleware assumes TCP-based connection pooling, where

By Koen M. Vermeulen