The SOAP connector enables LoopBack applications to interact with SOAP-based web services.
Page Contents

loopback-connector-soap

The SOAP connector enables LoopBack applications to interact with SOAP-based web services described using WSDL.

For more information, see the LoopBack documentation.

Installation

In your application root directory, enter:

$ npm install loopback-connector-soap --save

This will install the module from npm and add it as a dependency to the application’s  package.json file.

Creating a data source

Use the Data source generator to add a SOAP data source to your application.

For LoopBack 2.x, with the API Connect toolkit:

$ apic create --type datasource

For LoopBack 2.x or 3.0, with StrongLoop tools:

$ slc loopback:datasource

Choose “SOAP webservices” as the data source type when prompted.

SOAP data source properties

The following table describes the SOAP data source properties you can set in datasources.json.

Property Type Description
url String

URL to the SOAP web service endpoint. If not present, defaults to the location attribute of the SOAP address for the service/port from the WSDL document; for example:

<wsdl:service name="Weather">
  <wsdl:port name="WeatherSoap"
    binding="tns:WeatherSoap">
  <soap:address
    location="http://wsf.cdyne.com/WeatherWS/Weather.asmx" />
  </wsdl:port> ...
</wsdl:service>
wsdl String HTTP URL or local file system path to the WSDL file. Default is ?wsdl.
wsdl_options Object Indicates additonal options to pass to the SOAP connector, for example allowing self signed certificates. For example:
wsdl_options: {
  rejectUnauthorized: false,
  strictSSL: false,
  requestCert: true,
}
remotingEnabled Boolean

Indicates whether the operations are exposed as REST APIs.

To expose or hide a specific method, override with:

<Model>.<method>.shared = true | false;

operations Object Maps WSDL binding operations to Node.js methods. Each key in the JSON object becomes the name of a method on the model. See operations property below.
security Object security configuration. See security property below.
soapHeaders Array of objects. Custom SOAP headers. An array of header properties. For example:
soapHeaders: [{
 element: {myHeader: 'XYZ'}, // The XML element in JSON object format
 prefix: 'p1', // The XML namespace prefix for the header
 namespace: 'http://ns1' // The XML namespace URI for the header
}]

operations property

The operations property value is a JSON object that has a property (key) for each method being defined for the model. The corresponding value is an object with the following properties:

Property Type Description
service String WSDL service name
port String WSDL port name
operation String WSDL operation name

Here is an example operations property for the stock quote service:

operations: {
  // The key is the method name
  stockQuote: {
    service: 'StockQuote', // The WSDL service name
    port: 'StockQuoteSoap', // The WSDL port name
    operation: 'GetQuote' // The WSDL operation name
  },
  stockQuote12: {
    service: 'StockQuote',
    port: 'StockQuoteSoap12',
    operation: 'GetQuote'
  }
}

security property

The security property value is a JSON object witha scheme property. The other properties of the object depend on the value of that property. For example:

security: {
    scheme: 'WS',
    username: 'test',
    password: 'testpass',
    passwordType: 'PasswordDigest'
}
Scheme Description Other properties
WS WSSecurity scheme
  • username: the user name
  • password: the password
  • passwordType: default is 'PasswordText'
BasicAuth Basic auth scheme
  • username: the user name
  • password: the password
ClientSSL ClientSSL scheme
  • keyPath: path to the private key file
  • certPath: path to the certificate file

Example datasource.json

A complete example datasource.json:

{
  "WeatherServiceDS": {
    "url": "http://wsf.cdyne.com/WeatherWS/Weather.asmx",
    "name": "WeatherServiceDS",
    "connector": "soap",
    "wsdl": "http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL",
    "remotingEnabled": true,
    "operations": {
      "stockQuote": {
        "service": "StockQuote",
        "port": "StockQuoteSoap",
        "operation": "GetQuote"
      },
      "stockQuote12": {
        "service": "StockQuote",
        "port": "StockQuoteSoap12",
        "operation": "GetQuote"
      }
    }
  }
}

Creating a model from a SOAP data source

The SOAP connector loads WSDL documents asynchronously. As a result, the data source won’t be ready to create models until it’s connected. The recommended way is to use an event handler for the ‘connected’ event; for example:

ds.once('connected', function () {
   // Create the model
   var WeatherService = ds.createModel('WeatherService', {});
   //...
}

Extending a model to wrap and mediate SOAP operations

Once you define the model, you can extend it to wrap or mediate SOAP operations and define new methods. The following example simplifies the GetCityForecastByZIP operation to a method that takes zip and returns an array of forecasts.

// Refine the methods
WeatherService.forecast = function (zip, cb) {
    WeatherService.GetCityForecastByZIP({ZIP: zip || '94555'},
      function (err, response) {
        console.log('Forecast: %j', response);
        var result = (!err && response.GetCityForecastByZIPResult.Success) ?
        response.GetCityForecastByZIPResult.ForecastResult.Forecast : [];
        cb(err, result);
      });
};

The custom method on the model can be exposed as REST APIs. It uses the loopback.remoteMethod to define the mappings.

// Map to REST/HTTP
loopback.remoteMethod(
  WeatherService.forecast, {
    accepts: [{
      arg: 'zip',
      type: 'string',
      required: true,
      http: {
        source: 'query'
      }
    }],
    returns: {
      arg: 'result',
      type: 'object',
      root: true
    },
    http: {
      verb: 'get',
      path: '/forecast'
    }
  }
);

Use boot script to create model and expose APIs to API Explorer

The SOAP connector builds operations from WSDL asynchronously. To expose such methods over REST, you need to do the following with a boot script, such as server/a-soap.js:

module.exports = function(app, cb) {
  var ds = app.dataSources.WeatherServiceDS;
  if (ds.connected) {
    var weather = ds.createModel('weather', {}, {base: 'Model'});
    app.model(weather);
    process.nextTick(cb);
  } else {
    ds.once('connected', function() {
      var weather = ds.createModel('weather', {}, {base: 'Model'});
      app.model(weather);
      cb();
    });
  }
};

Examples

The [loopback-example-connector] (https://github.com/strongloop/loopback-example-connector/tree/soap) repository provides several examples in the soap branch:

Get stock quotes by symbols:  [stock-ws.js] (https://github.com/strongloop/loopback-example-connector/blob/soap/stock-ws.js). Run with the command:

$ node example/stock-ws

Get weather and forecast information for a given zip code:  [weather-ws.js] (https://github.com/strongloop/loopback-connector-soap/blob/master/example/weather-ws.js). Run with the command:

$ node example/weather-ws

Expose REST APIs to proxy the SOAP web services: [weather-rest.js] (https://github.com/strongloop/loopback-example-connector/blob/soap/weather-rest.js). Run with the command:

$ node example/weather-rest

View the results at  http://localhost:3000/explorer.