Tokyo
Tokyo

Reputation: 211

Async/Await with Lambda and Database Calls

After going through async/await docs I am still not able to figure out the error in my code. I am trying to do the following when the lambda is invoked.

  1. Log the request object
  2. Do Database Operation
  3. Log the response Object

All of these need to be done in sync.

The below is the code snipped of my logic

    var AWS = require('aws-sdk');
    var lambda = new AWS.Lambda({ region: 'ap-south-1' });
    var mysql = require('/opt/node_modules/mysql');
    var config = require('/opt/config.json');
    var con = mysql.createConnection({
     host: config.dbhost,
     user: config.dbuser,
     password: config.dbpassword,
     database: config.dbname,
    });

exports.handler = async function(event, context, callback) {
    context.callbackWaitsForEmptyEventLoop = false;
    let response = null;
    let errors = [];
    try {
        let body = JSON.parse(event.body);
        const email = body.email;
        const password = body.password;

        let loggerObject = {
            email: email,
            feature: 'LOGIN',
            request: JSON.stringify(body)
        };
        let loggerResponseCallback = await logRequest(loggerObject);
        console.log(loggerResponseCallback);
        const userValidationSQL = `SELECT QUERY`;
        await con.query(userValidationSQL, [email, password], async(userValidationError, userValidationResponse) => {
            if (userValidationError) {
                throw userValidationError;
            }
            console.log(" User Validation Response", userValidationResponse);
            loggerObject = {
                email: email,
                feature: 'LOGIN',
                response: JSON.stringify(userValidationResponse)
            }
            loggerResponseCallback = await logRequest(loggerObject);
            console.log(loggerResponseCallback);
            callback(null, {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin": "*"
                },
                body: JSON.stringify({ status: 'success', data: userValidationResponse }),
            }) //callback
        })
    }
    catch (error) {
        console.log(" catch========== ", error)
        callback(null, {
            statusCode: 400,
            headers: {
                "Access-Control-Allow-Origin": "*"
            },
            body: JSON.stringify({ status: 'error', message: 'Bad Request', error: errors }),
        })
    }
};



async function logRequest(loggerObject) {
    console.log("Invoking Logger Function");
    let params = {
        FunctionName: 'common-logger',
        InvocationType: 'RequestResponse',
        LogType: 'Tail',
        Payload: JSON.stringify(loggerObject)
    };

    await lambda.invoke(params, function(loggerError, loggerResponse) {
        if (loggerError) {
            console.log("Error in invoking Logger Function ", loggerError)
        }
        console.log('Logger Response:', loggerResponse);
        return loggerResponse;
    });
}

All the combinations of async/await that I try just don't seem to be working. Can someone please guide?

Update II:

With the below code i do manage to get them execute in sequence however i am not able to get the value from the second lambda function

var AWS = require('aws-sdk');
var mysql = require('/opt/node_modules/mysql');
var con = mysql.createConnection({
    host: config.dbhost,
    user: config.dbuser,
    password: config.dbpassword,
    database: config.dbname,
});

exports.handler = function(event, context, callback) {
    context.callbackWaitsForEmptyEventLoop = false;
    let response = null;
    let errors = [];
    try {
        let body = JSON.parse(event.body);
        const email = body.email;
        const password = body.password;
        
        let loggerObject = {
            email: email,
            feature: 'LOGIN',
        };
        let loggerResponseCallback = logRequest(loggerObject);
        console.log('First loggerResponseCallback:', loggerResponseCallback);
        const userValidationSQL = `SELECT Query`;
        con.query(userValidationSQL, [email, password], (userValidationError, userValidationResponse) => {
            if (userValidationError) {
                throw userValidationError;
            }
            console.log(" User Validation Response", userValidationResponse);
            loggerObject = {
                email: email,
                feature: 'LOGIN',
                method: 'POST',
            };
            loggerResponseCallback = logRequest(loggerObject);
            console.log('Second loggerResponseCallback:', loggerResponseCallback);
            callback(null, {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin": "*"
                },
                body: JSON.stringify({ status: 'success', data: userValidationResponse }),
            }) //callback
        })
    }
    catch (error) {
        console.log(" catch========== ", error)
        callback(null, {
            statusCode: 400,
            headers: {
                "Access-Control-Allow-Origin": "*"
            },
            body: JSON.stringify({ status: 'error', message: 'Bad Request', error: errors }),
        })
    }
};



async function logRequest(loggerObject) {
    var lambda = new AWS.Lambda({ region: 'ap-south-1' });
    console.log("Invoking Logger Function");
    let params = {
        FunctionName: 'common-logger',
        InvocationType: 'RequestResponse',
        LogType: 'Tail',
        Payload: JSON.stringify(loggerObject)
    };
    await lambda.invoke(params, function(loggerError, loggerResponse) {
        if (loggerError) {
            console.log("Error in invoking Logger Function ", loggerError)
        }
        console.log('Logger Response:', loggerResponse);
        return loggerResponse;
    });
}

My Common-Logger Lambda Function

var mysql = require('/opt/node_modules/mysql');
var config = require('/opt/config.json');
var con = mysql.createConnection({
    host: config.dbhost,
    user: config.dbuser,
    password: config.dbpassword,
    database: config.dbname,
});

exports.handler = (event, context, callback) => {
    context.callbackWaitsForEmptyEventLoop = false;
    console.log('invoked logger');
    let loggerId = -1;
    try {
        let email = null,
        
        const sql = 'INSERT QUERY';
        con.query(sql, [ email], (err, res) => {
            if (err) {
                console.log(err)
                throw err;
            }
            loggerId = res.insertId
            console.log('Logger Response:', loggerId);
            if (!correlationID) {
                const sql = 'UPDATE LOGGER SET correlationId = ? WHERE ID = ?';
                con.query(sql, [loggerId, loggerId], (err, res) => {
                    if (err) {
                        console.log(err)
                        throw err;
                    }
                    console.log("Updated CorrelationId for Record:" + loggerId);
                }); //con.query
            }
            callback(null, {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin": "*"
                },
                body: JSON.stringify({
                    status: 'success',
                    data: { "correlationId": loggerId }
                })
            })
        }); //con.query

    }
    catch (error) {
        console.log("catch", error);
    }
};

Find the AWS Logs attachedenter image description here

Upvotes: 1

Views: 528

Answers (1)

Hossam ELMansy
Hossam ELMansy

Reputation: 516

I refactored it for you, you can try it:

var AWS = require("aws-sdk");
var lambda = new AWS.Lambda({ region: "ap-south-1" });
var mysql = require("/opt/node_modules/mysql");
var config = require("/opt/config.json");
var con = mysql.createConnection({
  host: config.dbhost,
  user: config.dbuser,
  password: config.dbpassword,
  database: config.dbname,
});

exports.handler = async function (event, context, callback) {
  context.callbackWaitsForEmptyEventLoop = false;
  let response = null;
  let errors = [];

  try {
    let body = JSON.parse(event.body);
    const email = body.email;
    const password = body.password;
    let loggerObject = {
      email: email,
      feature: "LOGIN",
      request: JSON.stringify(body),
    };

    let loggerResponseCallback = await logRequest(loggerObject);
    console.log(loggerResponseCallback);
    const userValidationSQL = `SELECT QUERY`;
    con.query(
      userValidationSQL,
      [email, password],
      async (userValidationError, userValidationResponse) => {
        if (userValidationError) {
          throw userValidationError;
        }
        console.log(" User Validation Response", userValidationResponse);
        loggerObject = {
          email: email,
          feature: "LOGIN",
          response: JSON.stringify(userValidationResponse),
        };
        loggerResponseCallback = await logRequest(loggerObject);
        console.log(loggerResponseCallback);
        callback(null, {
          statusCode: 200,
          headers: {
            "Access-Control-Allow-Origin": "*",
          },
          body: JSON.stringify({
            status: "success",
            data: userValidationResponse,
          }),
        }); //callback
      }
    );
  } catch (error) {
    console.log(" catch========== ", error);
    callback(null, {
      statusCode: 400,
      headers: {
        "Access-Control-Allow-Origin": "*",
      },
      body: JSON.stringify({
        status: "error",
        message: "Bad Request",
        error: errors,
      }),
    });
  }
};

async function logRequest(loggerObject) {
  console.log("Invoking Logger Function");
  let params = {
    FunctionName: "common-logger",
    InvocationType: "RequestResponse",
    LogType: "Tail",
    Payload: JSON.stringify(loggerObject),
  };
  try {
    const loggerResponse = await lambda.invoke(params).promise();
    console.log("Logger Response:", loggerResponse.Payload);
    return loggerResponse.Payload;
  } catch (loggerError) {
    console.log("Error in invoking Logger Function ", loggerError);
  }
}

Upvotes: 1

Related Questions