Search code examples
asynchronousasync-awaitaws-lambdainitializationaws-secrets-manager

AWS Lambda: Async Calls outside handler (initialization section, invoke lambda)


I would like to call an asynchronous function outside the lambda handler with by the following code:

var client;
(async () => {
    var result =  await initSecrets("MyWebApi");
    var secret = JSON.parse(result.Payload);
    client= new MyWebApiClient(secret.API_KEY, secret.API_SECRET); 
});

async function initSecrets(secretName) {
    var input = {
    "secretName" : secretName
    };
    var result = await lambda.invoke({
       FunctionName: 'getSecrets',
       InvocationType: "RequestResponse",
       Payload: JSON.stringify(input)
    }).promise();
    return result;
}

exports.handler = async function (event, context) {

    var myReq = await client('Request');
    console.log(myReq);
};

The 'client' does not get initialized. The same code works perfectly if executed within the handler. initSecrets contains a lambda invocation of getSecrets() which calls the AWS SecretsManager Has anyone an idea how asynchronous functions can be properly called for initialization purpose outside the handler?

Thank you very much for your support.


Solution

  • I ran into a similar issue trying to get next-js to work with aws-serverless-express.

    I fixed it by doing the below (using typescript so just ignore the :any type bits)

    const appModule = require('./App');
    let server: any = undefined;
    
    appModule.then((expressApp: any) => {
      server = createServer(expressApp, null, binaryMimeTypes);
    });
    
    function waitForServer(event: any, context: any){
      setImmediate(() => {
        if(!server){
          waitForServer(event, context);
        }else{
          proxy(server, event, context);
        }
      });
    }
    
    exports.handler = (event: any, context: any) => {
      if(server){
        proxy(server, event, context);
      }else{
        waitForServer(event, context);
      }
    }
    

    So for your code maybe something like

    var client = undefined;
    
    initSecrets("MyWebApi").then(result => {
        var secret = JSON.parse(result.Payload);
        client= new MyWebApiClient(secret.API_KEY, secret.API_SECRET)
    })
    
    function waitForClient(){
      setImmediate(() => {
        if(!client ){
          waitForClient();
        }else{
          client('Request')
        }
      });
    }
    
    exports.handler = async function (event, context) {
      if(client){
        client('Request')
      }else{
        waitForClient(event, context);
      }
    };