Legacy SOAP & WSDL-Based XML Web Services with API Gateways

Software may not come with an expiration date, but older systems and protocols often remain in production for extended periods. This is especially true for XML-based protocols and web services. Although these formats have largely fallen out of favor, they still exist and sometimes must be integrated with modern APIs.

This text explores how to integrate those legacy services into a modern API gateway. But first let’s have a look at the gateways from SOA days.

Early API Gateways

The first generation of API gateways was built on Service-Oriented Architecture (SOA) tools, featuring excellent support for web services and XML. However, these gateways often required hundreds of gigabytes of memory and were eventually replaced by more lightweight, modern solutions.

Modern API Gateways

Modern gateways—often implemented in nginx, Go, or C++—have a much smaller footprint than their SOA predecessors. Although these platforms typically offer strong JSON and YAML support (with plugins often written in Lua), they usually lack robust XML validation or WSDL capabilities. Nonetheless, as long as legacy protocols like SOAP or WSDL are transmitted over HTTP, API gateways can route them—even if they don’t inherently understand XML, SOAP, or WSDL. Beyond simple routing, they offer no additional legacy-specific support.

Legacy Support in Membrane API Gateway

The open-source Membrane API Gateway is built on the Java platform, providing all the libraries and tools needed for legacy SOA support. Consequently, Membrane consumes more memory than microgateways written in Go, typically requiring about 150–200 MB per instance—a significant amount for a service mesh with hundreds of services. Still, its overall footprint remains reasonable. The following examples demonstrate powerful plugins that enable seamless integration with legacy services.

Deploying a Web Service from WSDL

Membrane’s comprehensive WSDL support makes it easy to deploy a web service on the gateway. The configuration automatically reads details such as the endpoint address, path, and XML Schema definitions from the WSDL:

<soapProxy port="443" wsdl="city.wsdl"/>

The WSDL retrieved from the gateway is rewritten to route traffic through the gateway, with the service location now pointing to the gateway.

WSDL Rewriting im API Gateway
Image: Rewriting of WSDL locations at the API Gateway

Additionally, the soapProxy validates input and output messages against the XSD schema definitions in the WSDL, and the web services explorer below simplifies the testing and exploration of deployed web services.

Web Services Explorer Image: Web Services Explorer

Mocking a Web Service with SOAP Body Template

Membrane API Gateway simplifies creating SOAP responses by providing a convenient element.

<api port="2000">
  <path>/mock-service</path>
  <response>
      <soapBody pretty="true">
          <![CDATA[
            <getCityResponse xmlns="https://predic8.de/cities">
                <country>England</country>
                <population>8980000</population>
            </getCityResponse>
          ]]>
      </soapBody>
  </response>
  <return/>
</api>

With , you only need to specify the payload. The gateway automatically wraps it in a SOAP envelope and body, applying the correct namespaces—allowing you to focus on the essential SOAP content rather than the surrounding boilerplate.

Exposing SOAP Web Services as REST APIs

Legacy SOAP services are likely to persist long into the future—even if their “shelf life” has technically expired—but you might not want to connect to them using SOAP. Instead, you can expose them as REST APIs. The following example demonstrates how to convert a SOAP service into a REST API endpoint:

<api port="2000" method=”GET”>
  <path>/cities/{city}</path>
  <request>
      <soapBody>
          <![CDATA[
          <getCity xmlns="https://predic8.de/cities">
              <name>${pathParam['city']}</name>
          </getCity>
          ]]>
      </soapBody>
  </request>
  <response>
      <template contentType="application/json">
          {
          "country": "${property.country}",
          "population": "${property.population}"
          }
      </template>
      <setProperty name="country" value="${//country}" language="xpath"/>
      <setProperty name="population" value="${//population}" language="xpath"/>
  </response>
  <log/>
  <target method="POST" url="https://www.predic8.de/city-service"/>
</api>

XPath Support

In practice, the small details are often the most helpful. Through the gateway, Membrane offers not only JsonPath but also XPath as an expression language. You can leverage many plugins with XPath that read values from XML documents, allowing you to integrate modern API gateway features such as rate limiting or API keys with legacy XML-based web services.

<setProperty name="population" value="${//population}" language="xpath"/>
        

Summary

The Membrane API Gateway, leveraging the Java platform, bridges this gap by offering comprehensive legacy support—including automatic WSDL deployment, SOAP body templating, and the ability to expose SOAP services as REST APIs—while maintaining a reasonable footprint despite higher memory requirements.

Where to Start?

Have a look at the samples in the examples/web-services-soap folder of the distribution.