Node.ACS SOAP Web Service Integration


While Appcelerator Titanium provides means for creating client side integrations to SOAP web services, parsing XML on the client is a cumbersome task. And with the inclusion of underscore in Alloy, JSON parsing is just much simpler and more readable. However, many legacy Enterprise integrations are still employing SOAP 1.1 and 1.2 web services. Appcelerator’s Node.ACS and the node-soap package provide a scalable means of converting SOAP to JSON REST service as well as providing mobile optimization and providing an integration façade.

In this blog post, I will show an example of using Node.ACS and node-soap to create a Node.js service to expose a SOAP web service as a REST API. This is illustrated in the diagram below.

SOAP Web Service

I will use the CDYNE Weather SOAP web service for this example. The CDYNE WSDL can be found here:

This link will be required in the Node service we will create in the next section.

Click on the link above and view the XML as it defines the entire SOAP web service. Look for the GetCityWeatherByZIP service and see that it takes a string argument ZIP. You can also see the XML data returned by the SOAP service (Success, ResponseText, State, City, …). This is the service we will be working with.

CDYNE also provide a means of testing the web service here. Entering a zip code, such as 02446, displays the following response in a browser:

Node-Soap npm

We want to implement a Node.js REST service on Node.ACS that will receive the Zip code from the mobile client, make a call to the CDYNE SOAP web service and return the data to the client as JSON. Node-soap is a perfect solution since it is designed to connect to SOAP web services and Node.ACS naturally presents its interface as a REST web service.

The first step is to install the soap-node npm. Installing an npm for a Titanium project was described in a previous Appcelerator Developer Blog Post. More information about installation is also described on the node-soap Github site.

Creating a client and making a SOAP call is described on the node-soap site and shown below:

var soap = require('soap');
  var url = '';
  var args = {name: 'value'};
  soap.createClient(url, function(err, client) {
      client.MyFunction(args, function(err, result) {

Putting it All Together

The following Node.ACS service receives one argument, ZIP and uses node-soap to make a call to the GetCityWeatherByZIP SOAP web service and returns a reduced set of JSON data required by the Titanium mobile client (city, state and temperature).

function getData(req, res) {
    var soap = require('soap');
    var url = '';
    var args = {ZIP: req.body.ZIP};
    soap.createClient(url, function(err, client) {
        client.GetCityWeatherByZIP(args, function(err, result) {
            var response = {city: result.GetCityWeatherByZIPResult.City, state: result.GetCityWeatherByZIPResult.State, temp: result.GetCityWeatherByZIPResult.Temperature};

Client Code

The client code for calling this Node service using Node.ACS binding is shown below:

nodesoap.services_getData({ZIP:$.tf.value}, function(r,e){
    if(!e.success){"Error: "+e.error);
    $.label.text = "Temp for " +", "+r.state+": "+r.temp;

Client code using an HTTPClient request is shown below:

var xhr = Titanium.Network.createHTTPClient({
    onload: function() {
        var r=JSON.parse(this.responseText);
        $.label.text = "Temp for " +", "+r.state+": "+r.temp;
    onerror: function(e) {"error: " + e.error);   
    timeout: 10000,
});"POST", Ti.App.Properties.getString("acs-service-baseurl-nodesoap")+"/getData");
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({'ZIP': $.tf.value}));

For comparison sake, see the following code for making a client side SOAP request to the same SOAP web service:

var xhr = Titanium.Network.createHTTPClient({
    onload: function() {
        var doc = this.responseXML.documentElement; 
        $.label.text = "Temp for "+doc.getElementsByTagName('City').item(0).text +", "+doc.getElementsByTagName('State').item(0).text +": "+ doc.getElementsByTagName('Temperature').item(0).text;
    onerror: function(e) {"error: " + e.error);           },      timeout: 10000,
var soapRequest = "< ?xml version="1.0" encoding="utf-8"?>"+""+""+""+""+ $.tf.value +""+""+""+"";"POST", "");
xhr.setRequestHeader("Content-Type","text/xml", "charset=utf-8");
xhr.setRequestHeader("Content-Length", soapRequest.length);

This client side SOAP request requires construction of a complex SOAP header as well as complex parsing of the XML reply. Furthermore, if back end changes are made, the code must change to reflect the back end changes.

In this blog post, we saw how Node.ACS and the node-soap npm can be used to make SOAP integration very simple and efficient, eliminating the need for SOAP header construction and complex XML parsing.

Mobile optimization was achieved by reducing the payload to the data required by the app (city, state and temperature). Further mobile optimization can be achieved by aggregation with other data such as 7 day weather forecast before replying to the mobile client. Also, if the back end service should change in the future, the Node.ACS service is providing an integration façade so that the mobile application will not need to change; the changes can be isolated to the Node.ACS service.


  1. Iam a novice node JS developer.

    When I tried to npm install the soap module, it doesnt end successful. it errors out after few modules. I tried downloading the zip and using it inside the node js service but it fails with several internal modules not being available.

    Can you please share the complete code so that I can run and understand it better?

    • Sometimes with npm modules installed with the -g global param will fail based on your sys config. Often if you simply just try installing local to your app you will have success. So just do npm install foo
      Leave out the -g. And this will install the module in your modules folder

Comments are closed.