api-gateway is a free, open source api development & testing project written in Java and released under Apache-2.0. It has 656 GitHub stars, 186 forks and 29 open issues, and was last pushed 10 hours ago. On this registry it ranks #167 of 187 tracked projects in API Development & Testing, with 5 head-to-head comparisons available. It gained 12 stars over the last 30 tracked days.

What is api-gateway?

Membrane API Gateway is an Apache-2.0, Java-based API gateway that runs REST, OpenAPI, and GraphQL APIs on the same gateway as legacy XML, SOAP, and WSDL services, and it is aimed at integration and platform engineers who must connect modern clients to older enterprise back ends.

What it is

Membrane API Gateway is an open-source, Java platform gateway in the API development and integration tooling ecosystem, developed under the membrane organisation and documented at membrane-api.io. It runs either as a container, using the published predic8/membrane Docker image, or as a standalone Java application. On the modern side it handles REST, OpenAPI 3.0, 3.1 and 3.2, GraphQL, OAuth2, and JWT; on the legacy side it handles SOAP, WSDL, and XML, including XPath and JSONPath expressions, XSLT templates, and XML signatures. Behaviour is declared in YAML configuration files, with a minimal proxy defined by an apis.yaml file naming a port and a target.url.

The concrete problem it solves is the gap between SOAP/XML back ends and REST/JSON clients. Without a gateway, that gap is usually closed with hand-written, per-service adapters and manually maintained OpenAPI descriptions, and message validation is re-implemented for every service. Membrane replaces that work with configuration: wsdl2openapi transforms a Web Service's WSDL into an OpenAPI description, using the underlying XSD schema for the conversion between XML and JSON, and templates plus XSLT provide SOAP-to-REST conversion. Incoming messages can be validated against OpenAPI, JSON Schema, XSD, and WSDL documents rather than against bespoke parsing code.

Key capabilities

  • Deploys APIs directly from OpenAPI documents, supporting OpenAPI 3.0, 3.1, and 3.2, and validates messages against those specifications.
  • wsdl2openapi converts a WSDL into an OpenAPI description, reusing the underlying XSD schema for XML-to-JSON and JSON-to-XML transformation.
  • Full SOAP-to-REST and XML-to-JSON conversion through templates and XSLT, with XPath and JSONPath expressions for routing, filtering, and transformation.
  • Security for legacy services through WSDL and XSD message validation, XML message protection, and XML signatures, alongside OAuth2 and JWT for modern APIs.
  • API orchestration that coordinates calls to external APIs and processes collections with loops and conditional flows.
  • Extensibility through expressions and scripting in JSONPath, XPath, Groovy, and SpEL.
  • Deployment flexibility as the predic8/membrane container or as a Java application, with observability features and gateway support for AI, LLM, and MCP traffic.

Who uses it and how

  • Enterprise integration teams that must expose existing SOAP and WSDL services as REST APIs without rewriting the back ends.
  • Platform teams that keep XML contracts in place while giving JSON and GraphQL clients a gateway-managed entry point.
  • Organisations in regulated or contract-bound environments that need WSDL, XSD, OpenAPI, and JSON Schema validation at the edge so invalid messages do not reach internal systems.
  • Operators running a containerised gateway on port 2000, mounting an apis.yaml file into /opt/membrane/conf/ to configure proxying and routing.
  • Groups orchestrating several upstream APIs behind one facade, using loops and conditional flows instead of writing a separate integration service.

Getting started

Run the gateway as a container with docker run --rm -it -p 2000:2000 predic8/membrane, or download the distribution from the releases page, unzip it, and follow tutorials/getting-started/10-First-API.yaml. Custom configuration is supplied by mounting apis.yaml at /opt/membrane/conf/apis.yaml.

How it compares

The facts provided name no paid products that this project replaces, and no comparable gateways are named either, so on the evidence available it stands alone in this registry. No licence, hosting, or cost comparison can be drawn without inventing products.

When to use it — and when not to

A self-hoster must run and update a Java application or Docker container and maintain the YAML configuration themselves, and no fully managed hosting option appears in the facts. Teams without any XML, SOAP, or WSDL estate, or those who want a vendor-operated cloud gateway with no operational responsibility, should look elsewhere. The repository carries 29 open issues and places much of its documentation and tutorials on the external membrane-api.io site rather than inside the repository, so a reader should expect to work from that site alongside the source.

project readme (upstream, from github) — read inline

Membrane API Gateway

for REST, OpenAPI, and GraphQL with first-class Legacy Support for XML, SOAP, and WSDL

GitHub release Docker Pulls License

Built on the Java platform, Membrane bridges legacy and modern APIs. It supports XML-to-JSON transformation, WSDL-to-OpenAPI conversion,SOAP-to-REST integration, and validation against OpenAPI and WSDL.

For modern APIs, Membrane supports technologies such as OAuth 2, JWT, and AI, along with a broad range of transformation, and observability features. It is easy to set up and deploy, either as a container or as a Java application.

Try Membrane in 5 Minutes

Start the API Gateway

Run Membrane as a container or as a Java application:

docker run --rm -it -p 2000:2000 predic8/membrane

Open these URLs in your browser to access sample APIs:

Or call an API from the command line:

curl http://localhost:2000/shop/v2/products

Proxy Your First API

Create a file apis.yaml with the following content:

api:
  port: 2000
  target:
    url: https://apibin.io

Start Membrane with your configuration:

Linux/macOS:

docker run --rm -p 2000:2000 -v "$(pwd)/apis.yaml:/opt/membrane/conf/apis.yaml" predic8/membrane

Windows PowerShell:

docker run --rm -p 2000:2000 -v "${PWD}/apis.yaml:/opt/membrane/conf/apis.yaml" predic8/membrane

Requests to http://localhost:2000 are now forwarded to https://apibin.io.

Make the Getting Started Tutorial

  1. Download the Membrane distribution
  2. Unzip
  3. Open tutorials/getting-started/10-First-API.yaml in your text editor and follow the instructions.

Why Membrane

From OpenAPI and OAuth to SOAP, XML, LLMs, and MCP, Membrane bridges modern APIs and enterprise integration.

Native OpenAPI Support

Deploy APIs directly from OpenAPI documents, validate messages against them and even generate OpenAPI specifications from legacy WSDL. In addition to OpenAPI 3.0, and 3.1, Membrane also supports OpenAPI 3.2.

Legacy XML and Web Services Integration

wsdl2openapi transforms a Web Service's WSDL into an OpenAPI and uses the underlying XSD schema for the conversion between XML and JSON. Deploy a WSDL, and Membrane exposes the service as an API with an OpenAPI description.

XML and JSON are deeply integrated into Membrane. XPath and JSONPath expressions provide direct access to message data for routing, filtering, and transformation.

Templates and XSLT allow for flexible message transformation and SOAP-to-REST conversion.

XML and Web Services Security

Secure legacy services with WSDL and XSD message validation, XML message protection, and XML signatures.

OpenAPI, JSON Schema, XSD, and WSDL Validation

Validate messages against API and service specifications. Don't let invalid messages slip into your organization.

API Orchestration

Orchestrate calls to external APIs and process collections with loops and conditional flows.

Easy Configuration and Extensibility

Take a look at the samples below and the tutorials to see what just a few lines of configuration can do.

When you need more flexibility, extend Membrane with expressions and scripting using JSONPath, XPath, Groovy, or SpEL, or write your own plugin in Java. In most cases, custom Java code is not necessary.

Speed & Footprint

Although Membrane is written in Java, it delivers high performance with a low memory footprint. HTTP streaming, Keep-Alive, and non-blocking processing enable efficient resource utilization and high throughput. The Membrane distribution is only about 55 MB, making it smaller than many other API gateways.

On a single server Membrane can process 39,000 requests per second. However, raw throughput benchmarks often measure only simple proxying without message protection or transformation.

Membrane is implemented entirely in Java, from the HTTP engine to OpenAPI processing. This avoids the overhead of crossing between a native proxy core and a separate scripting runtime for plugins.

As a result, Membrane can maintain high performance even when multiple plugins for validation, security, and transformation are active. What matters is not performance in reduced benchmark setups, but performance under realistic gateway configurations.

What Can You Do With Membrane?

  • Expose and protect APIs for partners over the public Internet.
  • Secure APIs with OAuth 2.0, JWT, API keys, TLS, and message validation.
  • Modernize legacy services by integrating SOAP, XML, and WSDL with REST, JSON, and OpenAPI.
  • Transform messages between JSON, XML, SOAP, HTTP headers, query parameters, and other formats.
  • Route and control traffic with flexible rules, rate limiting, load balancing, and conditional processing.
  • Use Membrane as an outgoing gateway to control access to partner and public APIs.
  • Observe API traffic with logging, metrics, Prometheus, and OpenTelemetry tracing.
  • Use Membrane as an AI Gateway for LLM providers and MCP servers.
  • Replace maintenance-intensive Backend for Frontend (BFF) services with declarative gateway configuration where appropriate.
  • Embed Membrane into your own Java applications and products.
  • Deploy Membrane in containers, virtual machines, private clouds, or public clouds.

Membrane Features with Examples

For a quick overview of what you can do with Membrane, the sections below provide a selection of short examples and configuration snippets.

  1. OpenAPI Deployment, Validation and Swagger UI
  2. Legacy Web Services with SOAP and WSDL
  3. AI and LLM Gateway
  4. Routing
  5. Message Transformation
  6. Orchestration and Call Outs
  7. Scripting
  8. Security
  9. Traffic Control
  10. Operation

1. OpenAPI Deployment, Validation and Swagger UI

OpenAPI is a native feature in Membrane. The gateway supports OpenAPI 3.0, 3.1, and 3.2, including the QUERY HTTP method.

Membrane can deploy an API directly from an OpenAPI description. It uses the defined paths, schemas, operations, and backend URLs to configure routing and, optionally, validate incoming requests and outgoing responses.

api:
  port: 2000
  openapi:
    - location: openapi/fruitshop-v2-2-0.oas.yml
      validateRequests: true

Membrane lets you explore APIs deployed from OpenAPI APIs in a single overview page.

List of OpenAPI Deployments

For documentation and testing the gateway hosts also a Swagger UI for the deployed APIs.

Swagger UI

See: OpenAPI tutorial

2. Legacy Web Services with SOAP and WSDL

Integrate and modernize legacy SOAP web services.

WSDL to OpenAPI Conversion

Membrane can expose a SOAP web service described by WSDL as a REST API with an OpenAPI specification.

This configuration:

api:
  port: 2000
  flow:
    - wsdl2openapi:
        wsdl: mocks/partner.wsdl
        operations:
          getPartners:
            method: GET
            path: /partners
            tag: Partner
          getPartner:
            method: GET
            path: /partners/{id}
            tag: Partner
          createPartner:
            method: POST
            path: /partners
            tag: Partner
          updatePartner:
            method: PUT
            path: /partners/{id}
            tag: Partner
          deletePartner:
            method: DELETE
            path: /partners/{id}
            tag: Partner
  target:
    url: http://localhost:3000/partner-service

turns this WSDL into an OpenAPI specification including JSON schemas derived from the WSDL's XSD schemas:

OpenAPI from WSDL

After deploying this configuration, clients can send JSON requests to the REST API. Membrane transforms them into SOAP requests for the backend Web Service and converts the XML responses back to JSON.

The conversion uses the XML Schema definitions from the WSDL to map data precisely between JSON and XML.

Manual SOAP to REST Conversion

The easiest way to expose a SOAP Web Service as a REST API is to use the wsdl2openapi plugin described above.

For more control over the conversion, you can define the REST API manually and map individual REST endpoints to SOAP operations.

The following configuration accepts a request such as GET /cities/Tokio, creates a SOAP request for the backend service, and transforms the SOAP response into JSON:

api:
  port: 2000
  method: GET
  path:
    uri: /cities/{city}
  flow:
    - request:
        - soapBody:
            src: |
              <getCity xmlns="https://predic8.de/cities">
                  <name>${pathParam.city}</name>
              </getCity>
        - setHeader:
            name: SOAPAction
            value: https://predic8.de/cities/get
    - response:
        - template:
            contentType: application/json
            src: |
              {
                "country": ${xpath('//country')},
                "population": ${xpath('//population')}
              }
  target:
    # Change method to POST
    method: POST
    url: https://www.predic8.de/city-service

Note: Membrane automatically escapes expression values such as ${xpath(...)} for the specified content type.

See the SOAP to REST tutorial for more details.

API Configuration from WSDL

Membrane can create a SOAP proxy directly from a WSDL:

soapProxy:
  port: 2000
  wsdl: https://www.predic8.de/city-service?wsdl

After startup, Membrane exposes:

Message Validation against WSDL and XSD

The validator checks SOAP messages against a WSDL document including referenced XSD schemas.

soapProxy:
  port: 2000
  wsdl: https://www.predic8.de/city-service?wsdl
  flow:
    # Validates SOAP messages against the WSDL and XSDs
    - validator: {}

Web Services Security (WSS)

Legacy SOAP services protected with Web Services Security (WS-Security) may require credentials and an XML Signature.

api:
  port: 2000
  flow:
     - wsSecurity:
         secure:
           - usernameToken:
               username: alice
               password: secret
           - signature:
               references:
                 - by: BODY
                 - by: USERNAME_TOKEN
  target:
    url: http://localhost:2001

Membrane can create and validate WS-Security UsernameTokens and XML Signatures.

3. AI and LLM Gateway

Membrane can act as a gateway for Large Language Models (LLMs) and Model Context Protocol (MCP) servers, providing centralized access control, usage policies, and API key management.

MCP Protection

The mcpProtectionplugin sits in front of an MCP server and controls which tools clients can discover and call.

api:
  port: 2000
  flow:
    - mcpProtection:
        tools:
          - allow: getCustomers
          - allow: getOrders
          - deny: '.*'
  target:
    url: http://my-mcp-server

See the MCP protection tutorial.

LLM Gateway

The llmGateway plugin routes requests to LLM providers such as Anthropic Claude, OpenAI, and Google Gemini. It can centralize provider API keys and enforce policies for token usage and allowed models.

api:
  port: 2000
  flow:
    - llmGateway:
        claude: {}
        apiKey: <<Replace with your API_KEY>>
        policies:
          maxOutputTokens: 100000
          models:
            - claude-opus-4-8
            - claude-sonnet-5
        simpleStore:
          users:
            - name: alice
              apiKey: abc123
              tokens: 2000000
            - name: bob
              apiKey: qwertz
              tokens: 10000000
          limitResetPeriod: 86400
  target:
    url: https://api.anthropic.com

Instead of handing the API key to every developer, keep it in the gateway and issue per-user keys. Membrane authenticates the user, enforces a per-user token budget, restricts the allowed models, and forwards the request using the shared provider key.

See: LLM key sharing tutorial.

4. Routing

Membrane provides flexible routing based on HTTP properties and custom expressions.

# Only GET to /products on port 2000
api:
  port: 2000
  method: GET
  path: /products
  flow:
    - response:
        - static:
            src: Oui!
    - return:
        status: 200

There are many routing options:

Option Description
port Listening port
method HTTP method, e.g. GET, POST, QUERY
path Request path
host Hostname, e.g. api.predic8.de
test Custom expression, e.g. header['content-type'].startsWith('text/plain')

See the API reference documentation.

5. Message Transformation

POST to GET with Query Parameters

Transform a POST request such as:

POST /products
Content-Type: application/json

{"limit": 100, "sort": "name"}

into a GET request like GET /products?limit=100&sort=name using a URI template with JSONPath expressions:

api:
  port: 2000
  target:
    method: GET
    url: https://api.predic8.de/shop/v2/products?sort=${$.sort}&limit=${$.limit}
    language: jsonpath

Note: Membrane automatically escapes expression values such as ${$.sort} for the specified content type.

See the tutorial to transform from GET to POST.

Transformation between XML to JSON

Both converters use a heuristic mapping and do not require a JSON or XSD schema.

flow:
  - xml2Json: {}
flow:
  - json2Xml:
      root: order

See transformation tutorials for other ways to transform between XML and JSON.

Templates

Templates can transform request and response bodies using data from the current message or the environment.

Membrane uses a Groovy-based template engine with dynamic constructs such as loops and conditionals. Its syntax is similar to template engines commonly used in web applications.

The example creates a JSON document containing the names and values of the request's HTTP headers.

- template:
    contentType: application/json
    pretty: true
    src: |
      {
        <% header.eachWithIndex { e, i -> %>
          <% if (i > 0) { %>,<% } %>
          <%= e.key %>: <%= e.value %>
        <% } %>
      }

Templates can access message data using JSONPath, XPath, and Groovy.

6. Orchestration and Call Outs

Membrane can orchestrate calls to external APIs and process collections with loops and conditional flows.

The example iterates over a list of fruits and sends a POST request for each item:

api:
  port: 2000
  flow:
    - for:
        # Loops over a list of objects [{ "name": "Mango", "price": 1.23 }, ..]
        in: $.fruits
        language: jsonpath
        flow:
          - setBody:
              # Serialize the current item to a JSON string
              value: ${toJSON(it)}
          # callout to an external API
          - call:
              method: POST
              url: https://api.predic8.de/shop/v2/products
          - log:
              message: "Created product: ${it['name']}"
    - return:
        status: 200

See orchestration tutorials

7. Scripting

Scripts can inspect and modify requests, responses, and extend gateway behavior. This makes it possible to implement custom API logic for use cases such as:

  • Routing: Load balance requests across multiple backends
  • Error Handling: Create custom error responses
  • Orchestration: Chain multiple APIs together to form a complex workflow
  • Creating Responses: Tailor responses dynamically based on client requests or internal logic.
  • Mocking APIs: Simulate API behavior during testing or development phases.
  • Debugging and Tracing: Inspect incoming requests during development.
api:
  port: 2000
  flow:
    - groovy:
        src: |
          println "I'm executed in the ${flow} flow"
          println "HTTP Headers:\n${header}"
  target:
    url: https://api.predic8.de

You can write scripts in Groovy and JavaScript.

Conditional Processing With the ´if´-Statement

A Membrane flow does not have to follow a fixed sequence. The if and choose plugins let you execute parts of a flow only when specific conditions are met. A common use case is error handling.

api:
  port: 2000
  flow:
    - response:
        - if:
            test: statusCode >= 500
            flow:
              - static:
                  src: Failure!
  target:
    url: https://httpbin.org/status/500

8. Security

Membrane provides security features for protecting APIs, services, and backend systems.

API Keys

Incoming requests can be authenticated by validating an API key against keys stored in a file or database.

global:
  - apiKey:
      stores:
        - simple:
            - secret:
                value: aed8bcc4-7c83-44d5-8789-21e4024ac873
            - secret:
                value: 08f121fa-3cda-49c6-90db-1f189ff80756
      extractors:
        - header: X-Api-Key

Membrane also supports:

  • Defining permissions as scopes in OpenAPI and enforcing them with API keys.
  • Extracting API keys from headers, query parameters, or custom locations using expressions.
  • Role-based access control (RBAC) with fine-grained permissions.

See the API Key Tutorials

JSON Web Tokens

The API below only allows requests that present a valid JSON Web Token issued by Microsoft Azure Entra ID.

api:
  port: 2000
  flow:
    - jwtAuth:
        expectedAud: api://2axxxx16-xxxx-xxxx-xxxx-faxxxxxxxxf0
        jwks:
          jwksUris: https://login.microsoftonline.com/common/discovery/keys
  target:
    url: https://your-backend

OAuth2

Secure APIs with OAuth2

Use OAuth2/OpenID to secure endpoints against Google, Azure Entra ID, GitHub, Keycloak or Membrane Authentication Servers.

api:
  port: 2000
  flow:
    - oauth2Resource2:
        membrane:
          src: http://localhost:8000
          clientId: abc
          clientSecret: def
          scope: openid profile
          claims: username
          claimsIdt: sub
    - request:
        # Forward the authenticated user’s email to the backend in an HTTP header.
        - setHeader:
            name: X-EMAIL
            value: ${property['membrane.oauth2'].userinfo['email']}
  target:
    url: http://backend

Try the OAuth tutorial

Membrane as Authorization Server

The following example shows a minimal configuration for running Membrane as an OAuth 2.0 authorization server.

api:
  port: 8000
  flow:
    - oauth2authserver:
        issuer: http://localhost:8000
        location: logindialog
        consentFile: consentFile.json
        staticUserDataProvider:
          users:
            - username: john
              password: secret
              email: john@predic8.de
        staticClientList:
          clients:
            - clientId: abc
              clientSecret: def
              callbackUrl: http://localhost:2000/oauth2callback
        bearerToken: {}
        claims:
          value: aud email iss sub username
          scopes:
            - id: username
              claims: username
            - id: profile
              claims: username email

User accounts can be stored in a file, in an LDAP server or backed by a database.

SSL/TLS

This example enables TLS for connections from clients to the API Gateway:

api:
  port: 443
  ssl:
    keystore:
      location: keystore.p12
      password: changeit
    truststore:
      location: keystore.p12
      password: changeit
  target:
    url: http://backend

Membrane supports advanced TLS scenarios, including:

  • TLS termination at the API Gateway with optional TLS forwarding to the backend.
  • SNI-based routing.
  • Routing TLS connections without decrypting them.

See the TLS/SSL tutorial

XML, JSON, JSON-RPC and GraphQL Protection

Membrane protects APIs from risks associated with XML, JSON, JSON-RPC and GraphQL payloads.

api:
  port: 2000
  flow:
    - xmlProtection:
        maxAttributeCount: 3
        maxElementNameLength: 100
        removeDTD: true
    - return:
        status: 200

See the XML protection, JSON protection , JSON-RPC protection, and GraphQl protection references.

9. Traffic Control

Rate Limiting

Limit the number of incoming requests within a defined time period:

global:
  - rateLimiter:
      requestLimit: 1000
      requestLimitDuration: PT1H

Load Balancing

Distribute the workload across multiple API backend nodes.

api:
  port: 8080
  flow:
    - balancer:
        clusters:
          - name: Default
            nodes:
              - host: my.backend-1
                port: 4000
              - host: my.backend-2
                port: 4000
              - host: my.backend-3
                port: 4000

See the API loadbalancing examples

10. Operation

Monitoring with Prometheus and Grafana

Expose Membrane metrics for Prometheus:

api:
  port: 2000
  path:
    uri: /metrics
  flow:
    - prometheus: {}

The collected metrics can be visualized in a Grafana dashboard:

Grafana Dashboard for Membrane API Gateway

OpenTelemetry Integration

Membrane supports integration with OpenTelemetry. This enables detailed tracing of requests across Membrane and backend services.

OpenTelemetry Example

For working examples of Prometheus, Grafana and OpenTelemetry see the operation tutorial.

Community and Enterprise Support

Community Support

To get support from our community, post your questions to our discussions page @GitHub.

If you find a bug, report it using GitHub Issues. Please provide a minimal example that reproduces the issue and the version of Membrane you are using.

Enterprise-Grade Support

See commercial support options and pricing.

API Gateway eBook(Free Download)

Learn how API Gateways work through practical scenarios and real-world examples.

Download instantly. No registration required.

Participate in the API Tech Talk

Meet other Membrane users online to discuss API gateway operation and architecture. Membrane developers answer questions and welcome your feedback and feature requests.

Upcoming Topics

  • September 30, 2026 Legacy Integration with XML, SOAP, and WSDL
  • October 28, 2026 Authentication with JSON Web Tokens (JWT)
  • November 25, 2026 MCP and AI Tool Integration
  • December 30, 2026 Message Transformation

Learn more

Frequently asked questions

Is api-gateway free to use?

api-gateway is open source under the Apache-2.0 licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does api-gateway do?

Java-based API Gateway bridging legacy and modern APIs with WSDL-to-OpenAPI, SOAP-to-REST, XML, OAuth2, and GraphQL.

What is api-gateway written in?

api-gateway is primarily written in Java. Its source is publicly available at https://github.com/membrane/api-gateway, and it has 656 GitHub stars.