AWS Lambda - Função no NODEJS

Nodejs é uma das linguagens que a função AWS Lambda suporta. As versões suportadas com nodejs são v6.10 e v8.10. Neste capítulo, aprenderemos em detalhes sobre as várias funcionalidades da função AWS Lambda no NODEJS.

Handler em NodeJS

Para escrever a função AWS Lambda em nodejs, devemos primeiro declarar um manipulador. O manipulador em nodejs é o nome do arquivo e o nome da função de exportação. Por exemplo, o nome do arquivo éindex.js e o nome da função de exportação é lambda handler, então seu manipulador correspondente é index.lambdahandler

Observe um manipulador de amostra mostrado aqui -

exports.lambdahandler = function(event, context, callback) {   //code goes here}

Params to Handler

Handler é o núcleo principal para a construção da função Lambda. O manipulador leva três parâmetros:event, context e callback.

Parâmetro de Evento

Possui todos os detalhes do evento acionado. Por exemplo, se estivermos usando a função Lambda para ser disparada no S3, o evento terá detalhes do objeto S3.

Parâmetro de Contexto

Ele contém os detalhes do contexto, como as propriedades e os detalhes de configuração da função Lambda.

Função de retorno de chamada

Ajuda a dar detalhes ao chamador. A estrutura do retorno de chamada é a seguinte -

callback(error, result);

Os parâmetros da função de retorno de chamada são explicados abaixo -

Error −Ele terá detalhes se algum erro ocorreu durante a execução da função Lambda. Se a função Lambda for bem-sucedida,null pode ser passado como o primeiro parâmetro para a função de retorno de chamada.

Result −Isso fornecerá os detalhes da execução bem-sucedida da função lambda. Se ocorrer um erro, o parâmetro do resultado será ignorado.

Note −Não é obrigatório usar a função de retorno de chamada no AWS Lambda. Caso não haja função de retorno de chamada, o manipulador irá retorná-lo como nulo.

As assinaturas de retorno de chamada válidas são fornecidas abaixo -

callback();                // It will return success, but no indication to the caller
callback(null);            // It will return success, but no indication to the caller
callback(null, "success"); // It will return the success indication to the caller
callback(error);           //  It will return the error indication to the caller

Sempre que o AWS Lambda é executado, os detalhes do retorno de chamada, como erro ou sucesso, são registrados no AWS CloudWatch junto com as mensagens do console, se houver.

Trabalhando com AWS Lambda em Nodejs8.10

Vamos entender como trabalhar com o AWS Lambda em nodejs8.10 e invocar a função de forma sincronizada e assíncrona.

Invocando a Função Lambda em modo de sincronização

O exemplo a seguir dá uma ideia sobre como invocar a função Lambda de forma sincronizada -

exports.handler = function(event, context, callback) {
   let arrItems = [4,5,6,8,9,10,35,70,80,31];
   function countevennumbers (items) {
      return new Promise(resolve => {
         setTimeout(() => {
            let a = 0;
            for (var i in items) {
               if (items[i] % 2 == 0) {
                  a++;
               } 
            }
            resolve(a);
         },2000);
      });
   }
   let evennumber = countevennumbers(arrItems);
   callback(null,'even numbers equals ='+evennumber);
};

Você pode observar a seguinte saída após testar este código no console da AWS -

Observe que a saída do código acima é um objeto de promessa. Ele não fornece a contagem, pois a contagem é incrementada dentro de um setTimeout e a chamada da função não espera pela execução dentro de setTimeout e retorna o objeto de promessa.

Se tivéssemos async/await na função de manipulador obterá a saída exata de da função lambda.

Invocando o Handler de maneira assíncrona

O exemplo a seguir dá uma ideia sobre como invocar a função Lambda de maneira assíncrona -

exports.handler = async function(event, context, callback) {
   let arrItems = [4,5,6,8,9,10,35,70,80,31];
   function countevennumbers (items) {
      return new Promise(resolve => {
         setTimeout(() => {
            let a = 0;
            for (var i in items) {
               if (items[i] % 2 == 0) {
                  a++;
               } 
            }
            resolve(a);
         }, 2000);
      });
   }
   let evennumber = await countevennumbers(arrItems);
   callback(null,'even numbers equals ='+evennumber);
};

Nós adicionamos async e awaitno código acima. Quando usamosawaitao lado da chamada de função, a execução pausa até que a promessa dentro da função seja resolvida. Observe queawait é válido apenas para async funções.

Você pode observar a seguinte saída após testar este código no console da AWS -

ContextDetails em NodeJS

O objeto de contexto fornece detalhes como o nome da função Lambda, tempo restante em milissegundos, ID da solicitação, nome do grupo de Cloudwatch, detalhes de tempo limite etc.

As tabelas a seguir mostram a lista de métodos e atributos disponíveis com o objeto de contexto -

Método disponível para objeto de contexto

Sr. Não Nome e descrição do método
1

getRemainingTimeInMillis()

Este método fornece o tempo restante em milissegundos até que a função Lambda termine a função

Atributos disponíveis para o objeto de contexto

Sr. Não Nome e descrição do atributo
1

functionName

Isso dá o nome da função AWS Lambda

2

functionVersion

Isso dá a versão da função AWS Lambda executando

3

nvokedFunctionArn

Isso fornecerá detalhes do ARN.

4

memoryLimitInMB

Isso mostra o limite de memória adicionado ao criar a função Lambda

5

awsRequestId

Isso fornece o ID de solicitação da AWS.

6

logGroupName

Isso dará o nome do grupo Cloudwatch

7

logStreamName

Isso fornecerá o nome do fluxo de log do Cloudwatch onde os logs são gravados.

8

identity

Isso fornecerá detalhes sobre o provedor de identidade cognito amazon quando usado com o aws mobile sdk.

Os detalhes fornecidos são os seguintes -

  • identity.cognito_identity_id
  • identity.cognito_identity_pool_id
9

clientContext

Isso fornecerá detalhes do aplicativo cliente quando usado com o aws mobile sdk. Os detalhes fornecidos são os seguintes -

  • client_context.client.installation_id
  • client_context.client.app_title
  • client_context.client.app_version_name
  • client_context.client.app_version_code
  • client_context.client.app_package_name
  • client_context.custom - possui ditado de valores personalizados do aplicativo cliente móvel
  • client_context.env - possui detalhes de ambiente do AWS Mobile SDK

Veja o exemplo a seguir para ter uma ideia melhor sobre o objeto de contexto -

exports.handler = (event, context, callback) => {
   // TODO implement
   console.log('Remaining time =>', context.getRemainingTimeInMillis());
   console.log('functionName =>', context.functionName);
   console.log('AWSrequestID =>', context.awsRequestId);
   console.log('logGroupName =>', context.log_group_name);
   console.log('logStreamName =>', context.log_stream_name);
   console.log('clientContext =>', context.clientContext);
   callback(null, 'Name of aws Lambda is=>'+context.functionName);
};

Você pode observar a seguinte saída após testar este código no console da AWS -

Você pode observar a seguinte saída de log após testar este código no console AWS -

Login no NodeJS

Podemos usar console.log para registrar em NodeJS. Os detalhes de registro podem ser obtidos do serviço CloudWatch com a função Lambda.

Observe o seguinte exemplo para um melhor entendimento -

exports.handler = (event, context, callback) => {
   // TODO implement
   console.log('Logging for AWS Lamnda in NodeJS');
   callback(null, 'Name of aws Lambda is=>'+context.functionName);
};

Você pode observar a seguinte saída após testar este código no console da AWS -

Você pode observar a seguinte captura de tela do CloudWatch -

Tratamento de erros em NodeJS

Vamos entender como a notificação de erro é feita no NodeJS. Observe o seguinte código -

exports.handler = function(event, context, callback) {
   // This Source code only throws error. 
   var error = new Error("something is wrong");
   callback(error);   
};

Você pode observar o seguinte na saída do log -

Os detalhes do erro são fornecidos no retorno de chamada da seguinte forma -

{
   "errorMessage": "something is wrong",
   "errorType": "Error",
   "stackTrace": [    "exports.handler (/var/task/index.js:2:17)"  ]
}