NodeJS Soap service - Return synchronous response client

413 Views Asked by At

I am hosting Soap server in NodeJS via 'strong-soap' library. I followed the standard example given in the official documentation here: strong-soap

It works fine when I send back a response immediately. However, my implementation of the web service function requires a DB call to update a record before sending response.

My Soap Service implementation goes something like this:

var myService = {
UpdateService: {
    UpdatePort: {
        UpdateCps: function(args) {
             //return {
             //        StatusCode: 0,
             //        StatusDesc: "Update successful"
             //};

            utils.connectDB(function (err, connection) {
                if(err){
                    return {
                        StatusCode: 1,
                        StatusDesc: "Error connecting to DB"
                    };
                }
                connection.execute(
                    queryString, 
                    {
                        args
                    },{
                        autoCommit: true
                    }, function (err, results) {
                        if (err) {
                            utils.releaseConnection(connection);
                            return {
                                StatusCode: 1,
                                StatusDesc: "Error Updating Request ID"
                            };
                        }
                        utils.releaseConnection(connection);
                        return {
                            StatusCode: 0,
                            StatusDesc: "Update successful"
                        }
                    });
                }
            );
        }
    }
}

Issue I am facing is that the response I am returning from the inner function after the DB call (success or error) is not being returned back to the SOAP client. The call flow terminates after invoking the inner function. I cannot make the function a callback(asynchronous) as the caller (SOAP client) is expecting a 'synchronous' response. What am I missing?

How can I make the call synchronous so that response is sent back to the client only after the DB update?

Thanks in advance for the help!

1

There are 1 best solutions below

0
On

I managed to figure out the problem with my code.

  1. I had to change the function signature from

    UpdateCps: function(args) to UpdateCps: function(args, callback). My interpretation of callback was that there would be a callback passed by the caller (which was wrong).

  2. I used 'Promise' to ensure the 'callback' was invoked only after the DB operation completes.

These two changes fixed my issue. The final code is as below:

UpdateCps: function(args, callback) {
            let soapResponse = {};


            let promise = new Promise((resolve, reject) => {
                utils.connectDB(function (err, connection) {
                    if(err){
                        soapResponse = {
                            StatusCode: 1,
                            StatusDesc: "Error connecting to DB"
                        }
                        resolve(soapResponse);
                        return;
                    }
                    connection.execute(
                        queryString,
                        args,
                        {
                            autoCommit: true
                        },
                        function (err, results) {
                            if (err) {
                                logger.error('Error Updating Request ID');
                                connection.release(function (err) {
                                    if (err) {
                                        logger.error(err.message);
                                    }
                                });

                                soapResponse = {
                                    StatusCode: 1,
                                    StatusDesc: "Error Updating Request ID"
                                }
                                resolve(soapResponse);
                                return;
                            }
                            utils.releaseConnection(connection);
                            soapResponse = {
                                StatusCode: 0,
                                StatusDesc: "Update successful for Request ID"
                            }
                            resolve(soapResponse);
                        });
                    });
                });

            promise.then(result => {
                soapResponse = result;
                callback(soapResponse)
            });
        }
    }