Search code examples
node.jsaws-lambdaserverless-frameworknode-soap

AWS Lambda node-soap function (serverless framework)


I am testing a call to a SOAP service using node-soap library. This works fine as a standalone node.js app and the SOAP service responds, however when I package the same code up as a serverless AWS lambda function (using serverless framework, but also executed directly in AWS lambda), it doesn’t appear to create the soap client.

Any thoughts on why this might be happening?

export async function main(event, context) {
    var soap = require('soap');
    var url = 'https://service.blah.co.uk/Service/Function.asmx?wsdl';

    var soapOptions = {
        forceSoap12Headers: true
    };

    var soapHeader = {
        'SOAPAction': 'http://www.blah.co.uk/Services/GetToken'
    };

    var params = {
        xmlMessage: message
    };

    console.log(JSON.stringify(params));

    soap.createClient(url, soapOptions, function (err, client) {
        //the serverless AWS lambda function never reaches this point (deployed and invoked locally)

        console.log("In create client")
        if (err) console.log(err);
        client.addSoapHeader(soapHeader);
        client.GetToken(params, function (err, data) {
            console.log(data);
        });
    });
}

Solution

  • I have created a very minimal working example using async/await. Rather using the old style callback approach, just invoke soap.createClientAsync(url).

    Here's the code:

    'use strict';
    const soap = require('soap');
    module.exports.hello = async (event, context) => {
    
        const url = 'http://www.thomas-bayer.com/axis2/services/BLZService?wsdl';
    
        const client = await soap.createClientAsync(url)
    
        console.log(client)
    
        return {
          statusCode: 200,
          message: 'It works!'
        }
    }
    

    And here are the logs (partially):

    enter image description here

    EDIT: Function's output (via AWS's Lambda Console)

    enter image description here

    EDIT 2 - The REAL problem

    Check the link above around async/await. The async keyword will execute asynchronously and will return a Promise. Since it's an asynchronous function, your Lambda is being terminated before it could actually execute your callback.

    Using async/await will make your code simpler and will have you stop beating your brains out for such a small thing like this.