Exposing SOAP webservice as REST with Node.js

Vishu Guntupalli
Intelicloud
Published in
3 min readFeb 22, 2015

If you are an enterprise Java developer like me, chances are you are very likely to produce or consume SOAP webservices.I had this thought what if I wanted to expose a SOAP webservice as a RESTful webservice, not writing a new web service but expose an existing SOAP web service, like take its WSDL and expose all the functions in it as RESTful operations. One way I figured to do that is with Node.js.

The SOAP webservice I have chosen to expose is http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL, here is a snapshot of all the functions exposed by the above ws.

Snip20150221_1

We will be using the following NPM packages in our process

var loopback = require(‘loopback’);
var path = require(‘path’);
var lcs = require(‘loopback-connector-soap’);

The above WS doesn’t use any authentication for validating the requests to it, but many WS do and our RESTful webservice must have the authentication info as it would be used to authenticate any requests being made to the SOAP ws. The address of the WSDL and the authentication info is to be provided after the NPM imports(java slang).

var ds = loopback.createDataSource(‘soap’,
{
connector: lcs,
security: {
scheme: ‘WS’,
created: null,
//username: ‘username’,
//password: ‘password’,
//passwordType: ‘PasswordText’},
remotingEnabled: true,
wsdl: ‘http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL',
});

The next step is to create a model for exposing the functions of SOAP webservice as RESTful functions.
We do that once our script has connected to the SOAP webservice, so all this would be in the callback after the connection has been established.

ds.once(‘connected’, function () {
var weatherService = ds.createModel(‘weatherService’, {});
weatherService.getCityForecastByZIP = function(zip, cb){
weatherService.GetCityForecastByZIP({ZIP : zip},
function(err, response){
console.log(“The weather forecast is : %j”, response);
var result = (!err) ? response.GetCityForecastByZIPResult : [];
cb(err, result);
});
};

As you can see in getCityForecastByZIP function above, it takes in the ZIP code as the parameter and the parameters passed to the function would depend on how many parameters does your web service require. Inside the function I make a call to the actual SOAP function by specifying the correct function name and passing in the appropriate parameters. There is one thing to be remembered that the name of the parameters during the actual call must be same as the parameter names in SOAP call as the parameters must be placed appropriately. The result from the actual call is handled in its callback, loopback connector soap also unmarshales the XML into JSON for us which is always a convenience.

Loopback-soap-connector by default would only show all the functions specified by the SOAP ws, we need to customize or specify the functions which we want to expose as RESTful functions by telling it the parameters it would accept and the response it would provide, the type of RESTful call GET/POST etc and the custom path.

loopback.remoteMethod(weatherService.getCityForecastByZIP, 
{ accepts: [{arg: ‘ZIP’, type: ‘string’, required: true,
http: {source: ‘query’}}],
returns: {arg: ‘result’, type: ‘object’, root: true},
http: {verb: ‘get’, path: ‘/zip’}
});

To get a good visual of the functions provided by the SOAP ws, I am using loopback-explorer


try
{
var explorer = require(‘loopback-explorer’)(app);
app.use(‘/explorer’, explorer);
app.once(‘started’, function (baseUrl) {
console.log(‘Browse your REST API at %s%s’, baseUrl, explorer.route);
});
}
catch (e) {
console.log(‘Run `npm install loopback-explorer` to enable the LoopBack explorer’);
}

Here is a snapshot of making a RESTful call to get the weather forecast by ZIP made through loopback-explorer.

Snip20150222_2

As you can see we have the ZIP as input and the result we get back is in the form of JSON. Hope this post was helpful to you guys, please leave a comment if you have any questions. Thanks.

BTW here is the github link for loopback-soap-connector https://github.com/strongloop/loopback-connector-soap. Cheers.

--

--

Vishu Guntupalli
Intelicloud

Software engineer/architect, Entrepreneur, AWS, Python, Data, Cloud