Definir el controlador de las funciones de Lambda en Node.js
El controlador de la función de Lambda es el método del código de la función que procesa eventos. Cuando se invoca una función, Lambda ejecuta el método del controlador. La función se ejecuta hasta que el controlador devuelve una respuesta, se cierra o se agota el tiempo de espera.
Temas
Conceptos básicos del controlador de Node.js
La siguiente función de ejemplo registra el contenido del objeto de evento y devuelve la ubicación de los registros.
nota
Esta página muestra ejemplos de controladores de módulos CommonJS y ES. Para obtener más información sobre la diferencia entre estos dos tipos de controladores, consulte Designación de un controlador de funciones como módulo de ES.
Al configurar una función, el valor del controlador es el nombre del archivo y el nombre del método del controlador exportado, separados por un punto. El valor predeterminado en la consola y para ejemplos de esta guía es index.handler
. Esto indica el método handler
que se exporta desde el archivo index.js
.
El tiempo de ejecución pasa argumentos al método del controlador. El primer argumento es el objeto event
, que contiene información del invoker. El invocador pasa esta información como una cadena con formato JSON cuando llama a Invoke y el runtime la convierte en un objeto. Cuando un servicio de AWS invoca su función, la estructura del evento varía en función del servicio.
El segundo argumento es el objeto context, que incluye información sobre la invocación, la función y el entorno de ejecución. En el ejemplo anterior, la función obtiene el nombre de flujo de registro del objeto context y lo devuelve al invocador.
También puede utilizar un argumento de devolución de llamada, una función a la que puede llamar en los controladores non-async para enviar una respuesta. Le recomendamos que utilice async/await en lugar de devolución de llamadas. Async/await mejora la legibilidad, el manejo de errores y la eficiencia. Para obtener información sobre las diferencias entre async/await y las devoluciones de llamadas, consulte Uso de devolución de llamadas.
Denominación
Al configurar una función, el valor del controlador es el nombre del archivo y el nombre del método del controlador exportado, separados por un punto. El valor predeterminado de las funciones creadas en la consola y de los ejemplos de esta guía es index.handler
. Esto indica el método handler
que se exporta desde el archivo index.js
o index.mjs
.
Si crea una función en la consola con un nombre de archivo o un nombre de controlador de funciones diferente, debe editar el nombre del controlador predeterminado.
Para cambiar el nombre de controlador de la función (consola)
-
Abra la página Funciones
de la consola de Lambda y elija su función. -
Elija la pestaña Código.
-
Desplácese hacia abajo hasta el panel Configuración del tiempo de ejecución y elija Editar.
-
En Controlador, ingrese el nuevo nombre del controlador de funciones.
-
Seleccione Guardar.
Uso de async/await
Si su código realiza una tarea asíncrona, utilice el patrón async/await para asegurarse de que el controlador termina de ejecutarse. Async/await es una forma concisa y legible de escribir código asíncrono en Node.js, sin necesidad de devoluciones de llamadas anidadas ni promesas encadenadas. Con async/await, puedes escribir código que se lea como código sincrónico, sin dejar de ser asíncrono y sin bloqueo.
La palabra clave async
marca una función como asíncrona y la palabra clave await
detiene la ejecución de la función hasta que se resuelva una Promise
.
nota
Asegúrese de esperar a que se completen los eventos asincrónicos. Si la función regresa antes de que se completen los eventos asincrónicos, podría fallar o causar un comportamiento inesperado en la aplicación. Esto puede suceder cuando un bucle forEach
contiene un evento asincrónico. Los bucles forEach
esperan una llamada sincrónica. Para obtener más información, consulte Array.prototype.forEach()
En el siguiente ejemplo, se usa async/await para enumerar los buckets de Amazon Simple Storage Service.
nota
Antes de usar este ejemplo, asegúrese de que el rol de ejecución de la función tenga permisos de lectura de Amazon S3.
Uso de devolución de llamadas
Le recomendamos que utilice async/await para declarar el controlador de funciones en lugar de utilizar devolución de llamadas. Async/await es una mejor opción por diversas razones:
-
Legibilidad: el código async/await es más fácil de leer y entender que el código de devolución de llamada, que puede volverse difícil de seguir con rapidez y provocar un caos de devolución de llamadas.
-
Depuración y gestión de errores: depurar código basado en devoluciones de llamadas puede resultar difícil. La pila de llamadas puede resultar difícil de seguir y los errores se pueden pasar por alto con facilidad. Con async/await, puede utilizar bloques try/catch para gestionar los errores.
-
Eficiencia: las devoluciones de llamadas a menudo requieren cambiar entre diferentes partes del código. Async/await puede reducir la cantidad de cambios de contexto, lo que resulta en un código más eficiente.
Cuando utiliza devoluciones de llamadas en su controlador, la función prosigue con su ejecución hasta que el bucle de eventos
La función de devolución de llamada toma dos argumentos: un Error
y una respuesta. El objeto de respuesta debe ser compatible con JSON.stringify
.
La siguiente función de ejemplo comprueba una URL y devuelve el código de estado al invocador.
En el siguiente ejemplo, la respuesta desde Amazon S3 se devolverá al invocador tan pronto como esté disponible. El tiempo de espera que se ejecuta en el bucle de eventos se ha detenido y continuará ejecutándose la próxima vez que se invoque la función.
nota
Antes de usar este ejemplo, asegúrese de que el rol de ejecución de la función tenga permisos de lectura de Amazon S3.
Prácticas recomendadas de codificación para las funciones de Lambda en Node.js
Siga las directrices de la siguiente lista para utilizar las prácticas recomendadas de codificación al crear sus funciones de Lambda:
-
Separe el controlador de Lambda de la lógica del núcleo. Esto le permite probar las distintas unidades de la función con mayor facilidad. En Node.js, podría tener este aspecto:
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 las dependencias del paquete de implementación de la función. El entorno de ejecución AWS Lambda contiene varias bibliotecas. Para los tiempos de ejecución de Node.js y Python, estos incluyen los SDK de AWS. Para disponer del conjunto más reciente de características y actualizaciones de seguridad, Lambda actualizará periódicamente estas bibliotecas. Estas actualizaciones pueden introducir cambios sutiles en el comportamiento de la función de Lambda. Para disponer de un control total de las dependencias que utiliza la función, empaquete todas las dependencias con el paquete de implementación.
-
Minimice la complejidad de las dependencias. Son preferibles los marcos de trabajo más sencillos, ya que se cargan rápidamente al arrancar el entorno de ejecución.
-
Minimice el tamaño del paquete de implementación de acuerdo con las necesidades de su tiempo de ejecución. Esto reducirá la cantidad de tiempo que tarda el paquete de implementación en descargarse y desempaquetarse antes de la invocación.
-
Reutilice el entorno de ejecución para mejorar el rendimiento de la función. Inicialice los clientes de SDK y las conexiones de base de datos fuera del controlador de funciones y almacene localmente en caché los recursos estáticos en el directorio
/tmp
. Las invocaciones posteriores procesadas por la misma instancia de su función pueden reutilizar estos recursos. Esto ahorra costes al reducir el tiempo de ejecución de la función.Para evitar posibles filtraciones de datos entre las invocaciones, no utilice el entorno de ejecución para almacenar datos de usuario, eventos u otra información con implicaciones de seguridad. Si su función se basa en un estado mutable que no se puede almacenar en la memoria dentro del controlador, considere crear una función independiente o versiones independientes de una función para cada usuario.
-
Utilice una directiva keep-alive para mantener conexiones persistentes. Lambda purga las conexiones inactivas a lo largo del tiempo. Si intenta reutilizar una conexión inactiva al invocar una función, se producirá un error de conexión. Para mantener la conexión persistente, use la directiva keep-alive asociada al tiempo de ejecución. Para ver un ejemplo, consulte Reutilización de conexiones con Keep-Alive en Node.js.
-
Utilice variables de entorno para pasar parámetros operativos a su función. Por ejemplo, si está escribiendo en un bucket de Amazon S3, en lugar de codificar de forma rígida el nombre del bucket, configúrelo como una variable de entorno.
-
Evite utilizar invocaciones recursivas en la función de Lambda, en las que la función se invoca a sí misma o inicia un proceso que puede volver a invocarla. Esto podría producir un volumen no intencionado de invocaciones de la función y costos elevados. Si observa un volumen imprevisto de invocaciones, establezca la simultaneidad reservada de funciones en
0
inmediatamente para limitar todas las invocaciones de la función mientras actualiza el código. -
No utilice API no documentadas y no públicas en el código de la función de Lambda. Para tiempos de ejecución administrados de AWS Lambda, Lambda aplica periódicamente actualizaciones funcionales y de seguridad a las API internas de Lambda. Estas actualizaciones de las API internas pueden ser incompatibles con versiones anteriores, lo que conlleva consecuencias no deseadas, como errores de invocación si su función depende de estas API no públicas. Consulte la referencia de la API para obtener una lista de las API disponibles públicamente.
-
Escriba el código idempotente. Escribir el código idempotente para las funciones garantiza que los eventos duplicados se gestionen de la misma manera. El código debe validar y gestionar correctamente los eventos duplicados. Para obtener más información, consulte ¿Cómo puedo hacer que mi función de Lambda sea idempotente?
.