AWS Lambda (Node.js) calling SOAP service
Published: 2022-11-22 16:30:30

### REST service:
Uses HTTP for exchanging information between systems in several ways such as JSON, XML, Text etc.

### SOAP service:
A Protocol for exchanging information between systems over internet only using XML.

### Requirement:
Calling SOAP services from Lambda.
We'll use this npm package: https://www.npmjs.com/package/soap
With this npm package - its a 3 step process:
1. Create a soap client
2. Call SOAP method by passing JSON input. 
3. Convert XML output to JSON

#### Create SOAP client:
```
const soap = require('soap');
let client = await soap.createClientAsync(url);
```
_url_ - is the wsdl url. For example: http://sampledomainname/services/sampleserice?wsdl (just for representation - this wsdl url does not works).

wsdl doc has all the details. But if you are like me who can best understand JSON data then use _client.describe()_ to get soap service details in JSON format.
> console.log(client.describe());
Output log below:
```
{
  "SomeService": {
    "SomeServicePort": {
      "someServiceMethod": {
        "input": {
          "serviceRequest": {
            "field1": "xsd:string"
          }
        }
      }
    }
  }
}
```
_Convert JSON to XML (pass input to SOAP)_: soap npm package takes care of this conversion. Pass JSON, & converts to XML.

#### Call SOAP method by passing JSON input:
```
client.SomeService.SomeServicePort_http.someServiceMethod(args, function(err, result) {
    if(err) console.error("Error - ", err); 
    console.log(result); // is a javascript object
}, { postProcess: function(_xml) { 
    console.log('XML - ', _xml); //this prints the input XML
    return _xml.replace('test', 'newtest'); // any mapping or string conversion, add here.
}});
```

Consider this args JSON as input to soap method
> Let args = {
> "one":"1"
> }

The args JSON would be converted by soap npm package as below XML:

```
<?xml version=\"1.0\" encoding=\"utf-8\"?>
 <soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" 	xmlns:xsi=\"http://www.w3.org/2001/XMLSchema- instance\">
 	<soap:Body>
 		<ns1:someServiceMethod>
			<ns1:one>1</ns1:one>
		</ns1:someServiceMethod>
	</soap:Body>
 </soap:Envelope>
```

Before we discuss about response XML to JSON (result of soap call). Let's see how to use async/await way of calling soap method.
```
let resultArr = await client.someServiceMethodAsync(args);
```
Just add suffix _Async_ to the soap method you wish to call, would return a promise. Note the above call results an array with 4 elements in both success and failure scenarios.
> Array element 0: result is a javascript object. 
> Array element 1: rawResponse is the raw xml response string.
> Array element 2: soapHeader is the response soap header as a javascript object (contains WS Security info-so let us not log this!). 
> Array element 3: rawRequest is the raw xml request string.

So the Array element O is already converted the XML response to JSON. Let's put altogether below:
```
const soap= require('soap');
let client = await soap.createClientAsync("http://sampledomainname/services/sampleserice?wsdl");
let resultArr= await client.someServiceMethodAsync(args); console.log("Response JSON-, resultArr[0]);
```

### Secured Soap Call:
All enterprise soap services would require authentication and in below section let's discuss about WSSecurity.
> let wsSecurity = new soap. WSSecurity('username', 'password", options); client.setSecurity(wsSecurity):

Putting altogether:
```
const soap = require('soap');
let client = await soap.createClientAsync('http://sampledomainname/services/sampleserice?wsdl'); 
let options = {
  hasNonce: true,
  actor: 'actor'
}
let wsSecurity = new soap.WSSecurity('username', 'password', options); 
client.setSecurity(wsSecurity); 
let resultArr = await client.someServiceMethodAsync(args); 
console.log('Response JSON-', resultArr[0]);
```

Image by <a href="https://pixabay.com/users/splitshire-364019/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=407081">SplitShire</a> from <a href="https://pixabay.com//?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=407081">Pixabay</a>