/rest-via-soap

A hack to expose RESTful services via SOAP

Primary LanguageJavaThe UnlicenseUnlicense

Expose REST endpoints through a single SOAP service

The problem

At the time of writing we were building some REST APIs and then discovered that, due to constraints in our infrastructure, we could only expose SOAP services.

REST support was promised to come Soon™, but until then we had to do something. And that something was either to build a SOAP implementation for each available REST service or come up with some generic solution.

The solution

This project solves the problem described previously in a simple, generic and low-effort way.

A Servlet Filter called SoapProxyForRestApi is provided that:

  1. Accepts SOAP requests holding HTTP method, endpoint and payload for invoking REST service
  2. Invokes REST service as specified by the caller
  3. Responds to caller with a SOAP response holding HTTP status code and payload returned by REST endpoint

Example

  1. Assume we have a REST endpoint that can create Greeting instances. It is available at /api/greetings and accepts POST requests with simple JSON payloads.
  2. A client then wants to invoke it via SOAP and sends a message to /soap-api (where SoapProxyForRestApi is registered):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://g.rimsa.lt/rest-via-soap/" >
  <soapenv:Header />
  <soapenv:Body>
    <request method="POST" path="/api/greetings">{ "content" : "Hello!" }</request>
  </soapenv:Body>
</soapenv:Envelope>
  1. SoapProxyForRestApi then builds a POST request with { "content" : "Hello!" } payload and forwards it to /api/greetings
  2. REST endpoint creates a Greeting instance and responds with { "id" : 123 }
  3. SoapProxyForRestApi wraps it into the following SOAP response and sends it to the caller:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://g.rimsa.lt/rest-via-soap/">
  <SOAP-ENV:Header/>
  <SOAP-ENV:Body>
    <response status="200">{ "id" : 123 }</response>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Usage

  1. Clone this repo and run gradle publishToMavenLocal task to install this project into your local Maven repository
  2. Add a dependency to your project. For Maven, use the following:
<dependency>
  <groupId>com.github.grimsa</groupId>
  <artifactId>rest-via-soap</artifactId>
  <version>0.1</version>
</dependency>

For Gradle:

dependencies {
   compile 'com.github.grimsa:rest-via-soap:0.1'
}
  1. Register a filter on some path, e.g. /soap-api
<filter>
  <filter-name>soapProxyForRestApi</filter-name>
  <filter-class>com.github.grimsa.restviasoap.SoapProxyForRestApi</filter-class>
</filter>
<filter-mapping>
  <filter-name>soapProxyForRestApi</filter-name>
  <servlet-name>/soap-api</servlet-name>
</filter-mapping>
  1. Smile and send some SOAP requests to /soap-api

Limitations

  • HTTP Redirects are not supported