Definir o manipulador de função do Lambda em Node.js
O manipulador da função do Lambda é o método no código da função que processa eventos. Quando sua função é invocada, o Lambda executa o método do manipulador. A função é executada até que o manipulador retorne uma resposta, seja encerrado ou atinja o tempo limite.
Tópicos
Conceitos básicos do handler em Node.js
O exemplo de função a seguir registra em log o conteúdo do objeto de evento e retorna a localização dos logs.
nota
Esta página exibe exemplos de manipuladores de módulos CommonJS e ES. Para saber mais sobre a diferença entre esses dois tipos de manipulador, consulte Designar um manipulador de funções como módulo ES.
Quando você configura uma função, o valor da configuração do manipulador é o nome do arquivo e o nome do módulo do manipulador exportado, separados por um ponto. O padrão no console e nos exemplos deste guia é index.handler
. Isso indica o método do handler
que é exportado do arquivo index.js
.
O runtime transmite argumentos para o método do handler. O primeiro argumento é o objeto event
, que contém informações do chamador. O invocador passa essas informações como uma string no formato JSON ao chamar Invoke, e o runtime as converte em um objeto. Quando um serviço da AWS invoca a sua função, a estrutura do evento varia de acordo com o serviço.
O segundo argumento é o objeto de contexto, que contém informações sobre a invocação, a função e o ambiente de execução. No exemplo anterior, a função obtém o nome do fluxo de logs do objeto de contexto e o retorna para o invocador.
Também é possível usar um argumento de retorno de chamada, que é uma função que você pode chamar nos manipuladores não assíncronos para enviar uma resposta. Recomendamos o uso de async/await em vez dos retornos de chamada. Async/await oferece melhor legibilidade, tratamento de erros e eficiência. Para obter mais informações sobre as diferenças entre async/await e retornos de chamada, consulte Usar retornos de chamada.
Nomenclatura
Quando você configura uma função, o valor da configuração do manipulador é o nome do arquivo e o nome do módulo do manipulador exportado, separados por um ponto. O padrão para as funções criadas no console e para os exemplos deste guia é index.handler
. Isso indica o método de handler
que é exportado do arquivo index.js
ou index.mjs
.
Se você criar uma função no console usando um nome de arquivo ou nome de manipulador de funções diferente, deverá editar o nome do manipulador padrão.
Para alterar o nome do manipulador de funções (console)
-
Abra a página Funções
do console do Lambda e escolha sua função. -
Escolha a guia Código.
-
Role para baixo até o painel Configurações de runtime e escolha Editar.
-
Em Manipulador, insira o novo nome para seu manipulador de funções.
-
Escolha Salvar.
Usar async/await
Se o código realizar uma tarefa assíncrona, use o padrão async/await para garantir que a execução do manipulador seja finalizada. Async/await é uma forma concisa e legível de escrever código assíncrono em Node.js, sem a necessidade de retornos de chamada aninhados ou promessas de encadeamento. Com async/await, é possível escrever um código que seja lido como código síncrono e, ao mesmo tempo, seja assíncrono e sem bloqueio.
A palavra-chave async
marca uma função como assíncrona, e a palavra-chave await
pausa a execução da função até que uma Promise
seja resolvida.
nota
Aguarde a conclusão dos eventos assíncronos. Se a função retornar antes que os eventos assíncronos sejam concluídos, a função poderá falhar ou causar um comportamento inesperado em sua aplicação. Isso pode acontecer quando um loop forEach
contiver um evento assíncrono. Os loops forEach
esperam uma chamada síncrona. Para obter mais informações, consulte Array.prototype.forEach()
O próximo exemplo usa async/await para listar buckets do Amazon Simple Storage Service.
nota
Antes de usar esse exemplo, verifique se o perfil de execução da sua função tem permissões de leitura do Amazon S3.
Usar retornos de chamada
Recomendamos usar async/await para declarar o manipulador da função em vez de usar retornos de chamada. Async/await é a melhor opção por vários motivos:
-
Legibilidade: o código async/await é mais fácil de ler e entender do que o código de retorno de chamada, que pode logo se tornar difícil de seguir e transformar o retorno de chamada em um tormento.
-
Depuração e tratamento de erros: pode ser difícil depurar código baseado em retorno de chamada. A pilha de chamadas pode se tornar difícil de acompanhar, e os erros podem ser facilmente ignorados. Com async/await, você pode usar blocos try/catch para manipular erros.
-
Eficiência: retornos de chamada muitas vezes exigem alternância entre diferentes partes do código. O async/await pode reduzir o número de alternâncias de contexto, resultando em um código mais eficiente.
Quando você usa retornos de chamada no manipulador, a função continua em execução até que o loop de evento
A função de retorno de chamada usa dois argumentos: um Error
e uma resposta. O objeto de resposta deve ser compatível com JSON.stringify
.
O exemplo de função a seguir verifica um URL e retorna o código de status para o invocador.
No próximo exemplo, a resposta do Amazon S3 é retornada ao invocador assim que fica disponível. O tempo limite em execução no loop de evento é congelado e continuará sendo executado na próxima vez que a função for invocada.
nota
Antes de usar esse exemplo, verifique se o perfil de execução da sua função tem permissões de leitura do Amazon S3.
Práticas recomendadas de código para as funções do Lambda em Node.js
Adote as diretrizes da lista a seguir para usar as práticas recomendadas de codificação ao compilar suas funções do Lambda:
-
Separe o manipulador do Lambda da lógica central. Isso permite que você crie uma função mais fácil para teste de unidade. No Node.js isso pode ser semelhante a:
exports.myHandler = function(event, context, callback) { var foo = event.foo; var bar = event.bar; var result = MyLambdaFunction (foo, bar); callback(null, result); } function MyLambdaFunction (foo, bar) { // MyLambdaFunction logic here }
-
Controle as dependências no pacote de implantação da função. O ambiente de execução do AWS Lambda contém várias bibliotecas. Para os runtimes em Node.js e Python, os AWS SDKs estão incluídos. Para habilitar o conjunto de recursos e atualizações de segurança mais recente, o Lambda atualizará periodicamente essas bibliotecas. Essas atualizações podem introduzir alterações sutis ao comportamento de sua função do Lambda. Para ter controle total das dependências usadas por sua função, empacote todas as dependências em seu pacote de implantação.
-
Minimize a complexidade de suas dependências. Prefira frameworks mais simples que sejam carregados rapidamente no startup do ambiente de execução.
-
Minimize o tamanho do pacote de implantação às necessidades do runtime. Isso reduzirá a quantidade de tempo necessária para que seu pacote de implantação seja obtido por download e desempacotado antes da invocação.
-
Aproveite a reutilização do ambiente de execução para melhorar a performance da função. Inicialize clientes SDK e conexões de banco de dados fora do manipulador de funções e armazene em cache os ativos estáticos localmente no diretório
/tmp
. As invocações subsequentes processadas pela mesma instância da função podem reutilizar esses recursos. Isso economiza custos reduzindo o runtime da função.Para evitar possíveis vazamentos de dados entre invocações, não use o ambiente de execução para armazenar dados do usuário, eventos ou outras informações com implicações de segurança. Se sua função depende de um estado mutável que não pode ser armazenado na memória dentro do manipulador, considere criar uma função separada ou versões separadas de uma função para cada usuário.
-
Use uma diretiva de keep-alive para manter conexões persistentes. O Lambda limpa conexões ociosas ao longo do tempo. A tentativa de reutilizar uma conexão ociosa ao invocar uma função resultará em um erro de conexão. Para manter sua conexão persistente, use a diretiva keep-alive associada ao runtime. Para obter um exemplo, consulte Reutilizar conexões com keep-alive em Node.js.
-
Use variáveis de ambiente para passar parâmetros operacionais para sua função. Por exemplo, se estiver gravando em um bucket do Amazon S3, em vez fixar no código o nome do bucket em que você está gravando, configure o nome do bucket como uma variável de ambiente.
-
Evite usar invocações recursivas em sua função do Lambda, em que a função invoca a si mesma ou inicia um processo que pode invocar a função novamente. Isso pode levar a um volume não intencional de invocações da função e a custos elevados. Se você observar um volume não intencional de invocações, defina a simultaneidade reservada da função como
0
imediatamente para limitar todas as invocações da função enquanto atualiza o código. -
Não use APIs não documentadas e não públicas no código da função Lambda. Para os tempos de execução gerenciados pelo AWS Lambda, o Lambda aplica periodicamente atualizações funcionais e de segurança às APIs internas do Lambda. Essas atualizações internas da API podem ser incompatíveis com versões anteriores, gerando consequências não intencionais, como falhas de invocação, caso sua função tenha dependência nessas APIs não públicas. Consulte a referência da API para obter uma lista de APIs disponíveis publicamente.
-
Escreva um código idempotente. Escrever um código idempotente para suas funções garante que eventos duplicados sejam tratados da mesma maneira. Seu código deve validar eventos adequadamente e lidar corretamente com eventos duplicados. Para obter mais informações, consulte Como torno minha função do Lambda idempotente?
.