Cómo Usar AWS Lambda API para Serverless en 2026

Ashley Innocent

Ashley Innocent

25 March 2026

Cómo Usar AWS Lambda API para Serverless en 2026

Apidog para empresas

Despliegue local

SSO & RBAC

Conforme con SOC 2

Explorar Apidog Enterprise

Resumen

La API de AWS Lambda permite a los desarrolladores implementar, gestionar e invocar funciones sin servidor de forma programática. Utiliza autenticación IAM, puntos finales RESTful para la gestión de funciones, opciones de invocación asíncrona y síncrona, con límites de concurrencia a nivel de cuenta. Esta guía cubre la configuración de autenticación, la implementación de funciones, los patrones de invocación, el mapeo de fuentes de eventos y las estrategias de arquitectura sin servidor para producción.

Introducción

AWS Lambda procesa billones de solicitudes mensuales para más de 1 millón de usuarios activos. Para los desarrolladores que construyen aplicaciones sin servidor, herramientas de automatización o arquitecturas impulsadas por eventos, la integración de la API de Lambda no es opcional, es esencial para la infraestructura como código y las canalizaciones de CI/CD.

Esta es la realidad: los equipos que gestionan más de 50 funciones Lambda manualmente pierden entre 10 y 15 horas semanales en implementaciones, actualizaciones de configuración y monitorización. Una sólida integración de la API de Lambda automatiza las implementaciones, implementa lanzamientos azul-verde y permite un escalado dinámico basado en la demanda.

Esta guía detalla el proceso completo de integración de la API de AWS Lambda. Aprenderás sobre la autenticación IAM, la creación e implementación de funciones, los patrones de invocación (síncrona/asíncrona), el mapeo de fuentes de eventos, las arquitecturas por capas y las estrategias de implementación en producción. Al final, tendrás una integración de Lambda lista para producción.

button

¿Qué es la API de AWS Lambda?

AWS Lambda proporciona una API RESTful para gestionar funciones de cómputo sin servidor. La API gestiona:

Características Clave

Característica Descripción
API RESTful Puntos finales HTTPS estándar
Autenticación IAM Firma de AWS Versión 4
Invocación Asíncrona Procesamiento de eventos "disparar y olvidar"
Invocación Síncrona Patrón de solicitud-respuesta
Fuentes de Eventos Más de 200 integraciones de servicios de AWS
Capas Código y dependencias compartidos
Versiones/Alias Desplazamiento de tráfico y reversiones
Concurrencia Aprovisionada Elimina los "arranques en frío"

Soporte de Runtimes de Lambda

Runtime Versiones Caso de Uso
Node.js 18.x, 20.x Backends de API, procesamiento de eventos
Python 3.9, 3.10, 3.11 Procesamiento de datos, inferencia de ML
Java 11, 17, 21 Aplicaciones empresariales
Go 1.x APIs de alto rendimiento
Rust 1.x Funciones de baja latencia
.NET 6, 8 Cargas de trabajo de Windows
Ruby 3.x Aplicaciones web
Personalizado Cualquiera Runtimes basados en contenedores

Visión General de la Arquitectura de la API

Lambda utiliza la estructura de la API de servicios de AWS:

https://lambda.{region}.amazonaws.com/2015-03-31/

Versiones de la API

Versión Estado Caso de Uso
2015-03-31 Actual Todas las operaciones de Lambda
2018-01-31 API de Runtime Interfaz de runtime personalizada

Primeros Pasos: Configuración de la Autenticación

Paso 1: Crear Cuenta de AWS y Usuario IAM

Antes de acceder a la API:

  1. Visita la Consola de AWS
  2. Crea una cuenta de AWS
  3. Ve a la Consola de IAM > Usuarios > Crear Usuario
  4. Adjunta políticas de ejecución de Lambda

Paso 2: Generar Credenciales IAM

Crea claves de acceso para acceso programático:

# Método de AWS CLI
aws iam create-access-key --user-name lambda-deployer

# Salida: Almacena esto de forma segura
{
  "AccessKey": {
    "AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
    "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
  }
}

Nota de seguridad: Almacena las credenciales de forma segura:

# ~/.aws/credentials
[lambda-deployer]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

# O utiliza variables de entorno
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export AWS_DEFAULT_REGION="us-east-1"

Paso 3: Comprender la Firma de AWS Versión 4

Todas las solicitudes de la API de Lambda requieren la firma SigV4:

const crypto = require('crypto');

class AWSSigner {
  constructor(accessKeyId, secretAccessKey, region, service = 'lambda') {
    this.accessKeyId = accessKeyId;
    this.secretAccessKey = secretAccessKey;
    this.region = region;
    this.service = service;
  }

  sign(request, body = null) {
    const now = new Date();
    const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
    const dateStamp = amzDate.slice(0, 8);

    // Task 1: Create canonical request
    const hashedPayload = body ? crypto.createHash('sha256').update(body).digest('hex') : 'UNSIGNED-PAYLOAD';
    const canonicalUri = request.path;
    const canonicalQuerystring = request.query || '';
    const canonicalHeaders = `host:${request.host}\nx-amz-date:${amzDate}\n`;
    const signedHeaders = 'host;x-amz-date';
    const canonicalRequest = `${request.method}\n${canonicalUri}\n${canonicalQuerystring}\n${canonicalHeaders}\n${signedHeaders}\n${hashedPayload}`;

    // Task 2: Create string to sign
    const algorithm = 'AWS4-HMAC-SHA256';
    const credentialScope = `${dateStamp}/${this.region}/${this.service}/aws4_request`;
    const hash = crypto.createHash('sha256').update(canonicalRequest).digest('hex');
    const stringToSign = `${algorithm}\n${amzDate}\n${credentialScope}\n${hash}`;

    // Task 3: Calculate signature
    const kDate = this.hmac(`AWS4${this.secretAccessKey}`, dateStamp);
    const kRegion = this.hmac(kDate, this.region);
    const kService = this.hmac(kRegion, this.service);
    const kSigning = this.hmac(kService, 'aws4_request');
    const signature = this.hmac(kSigning, stringToSign, 'hex');

    // Task 4: Add authorization header
    const authorizationHeader = `${algorithm} Credential=${this.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;

    return {
      'Authorization': authorizationHeader,
      'X-Amz-Date': amzDate,
      'X-Amz-Content-Sha256': hashedPayload
    };
  }

  hmac(key, string, encoding = 'buffer') {
    return crypto.createHmac('sha256', key).update(string).digest(encoding);
  }
}

// Usage
const signer = new AWSSigner(
  process.env.AWS_ACCESS_KEY_ID,
  process.env.AWS_SECRET_ACCESS_KEY,
  'us-east-1'
);

Paso 4: Crear Cliente de la API de Lambda

const LAMBDA_BASE_URL = 'https://lambda.us-east-1.amazonaws.com/2015-03-31';

const lambdaRequest = async (path, options = {}) => {
  const url = new URL(`${LAMBDA_BASE_URL}${path}`);
  const method = options.method || 'GET';
  const body = options.body ? JSON.stringify(options.body) : null;

  const signer = new AWSSigner(
    process.env.AWS_ACCESS_KEY_ID,
    process.env.AWS_SECRET_ACCESS_KEY,
    'us-east-1'
  );

  const headers = signer.sign({ method, host: 'lambda.us-east-1.amazonaws.com', path }, body);

  const response = await fetch(url.toString(), {
    method,
    headers: {
      'Content-Type': 'application/json',
      ...headers,
      ...options.headers
    },
    body
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Lambda API Error: ${error.Message}`);
  }

  return response.json();
};

// Uso
const functions = await lambdaRequest('/functions');
console.log(`Encontradas ${functions.Functions.length} funciones`);

Alternativa: Usar el SDK de AWS

Para uso en producción, el SDK de AWS maneja la firma automáticamente:

const { LambdaClient, ListFunctionsCommand, CreateFunctionCommand, InvokeCommand } = require('@aws-sdk/client-lambda');

const lambda = new LambdaClient({ region: 'us-east-1' });

// Listar funciones
const listCommand = new ListFunctionsCommand({});
const result = await lambda.send(listCommand);

// Crear función
const createCommand = new CreateFunctionCommand({
  FunctionName: 'my-function',
  Runtime: 'nodejs20.x',
  Role: 'arn:aws:iam::123456789012:role/lambda-execution-role',
  Handler: 'index.handler',
  Code: {
    S3Bucket: 'my-bucket',
    S3Key: 'function.zip'
  }
});

const fn = await lambda.send(createCommand);

Gestión de Funciones

Creando una Función

Crea una función Lambda a través de la API:

const createFunction = async (functionConfig) => {
  const response = await lambdaRequest('/functions', {
    method: 'POST',
    body: {
      FunctionName: functionConfig.name,
      Runtime: functionConfig.runtime || 'nodejs20.x',
      Role: functionConfig.roleArn,
      Handler: functionConfig.handler || 'index.handler',
      Code: {
        S3Bucket: functionConfig.s3Bucket,
        S3Key: functionConfig.s3Key
      },
      Description: functionConfig.description || '',
      Timeout: functionConfig.timeout || 3,
      MemorySize: functionConfig.memorySize || 128,
      Environment: {
        Variables: functionConfig.environment || {}
      },
      Tags: functionConfig.tags || {}
    }
  });

  return response;
};

// Uso
const fn = await createFunction({
  name: 'order-processor',
  roleArn: 'arn:aws:iam::123456789012:role/lambda-execution-role',
  handler: 'index.handler',
  runtime: 'nodejs20.x',
  s3Bucket: 'my-deployments-bucket',
  s3Key: 'order-processor/v1.0.0.zip',
  description: 'Procesar pedidos de la cola SQS',
  timeout: 30,
  memorySize: 512,
  environment: {
    DB_HOST: 'db.example.com',
    LOG_LEVEL: 'info'
  }
});

console.log(`Función creada: ${fn.FunctionArn}`);

Subiendo Código Directamente

Para funciones pequeñas (<50MB comprimidas):

const fs = require('fs');
const path = require('path');

const createFunctionWithZip = async (functionName, zipPath) => {
  const zipBuffer = fs.readFileSync(zipPath);
  const base64Code = zipBuffer.toString('base64');

  const response = await lambdaRequest('/functions', {
    method: 'POST',
    body: {
      FunctionName: functionName,
      Runtime: 'nodejs20.x',
      Role: 'arn:aws:iam::123456789012:role/lambda-execution-role',
      Handler: 'index.handler',
      Code: {
        ZipFile: base64Code
      }
    }
  });

  return response;
};

// Empaquetar función
// zip -r function.zip index.js node_modules/
await createFunctionWithZip('my-function', './function.zip');

Actualizando el Código de la Función

Implementa una nueva versión de código:

const updateFunctionCode = async (functionName, updateConfig) => {
  const response = await lambdaRequest(`/functions/${functionName}/code`, {
    method: 'PUT',
    body: {
      S3Bucket: updateConfig.s3Bucket,
      S3Key: updateConfig.s3Key,
      Publish: updateConfig.publish || false
    }
  });

  return response;
};

// Uso
const updated = await updateFunctionCode('order-processor', {
  s3Bucket: 'my-deployments-bucket',
  s3Key: 'order-processor/v1.1.0.zip',
  publish: true // Crear nueva versión
});

console.log(`Actualizado a la versión: ${updated.Version}`);

Actualizando la Configuración de la Función

Modifica el tiempo de espera, la memoria, el entorno:

const updateFunctionConfig = async (functionName, config) => {
  const response = await lambdaRequest(`/functions/${functionName}/configuration`, {
    method: 'PUT',
    body: {
      Runtime: config.runtime,
      Handler: config.handler,
      Description: config.description,
      Timeout: config.timeout,
      MemorySize: config.memorySize,
      Environment: {
        Variables: config.environment
      }
    }
  });

  return response;
};

// Uso
const updated = await updateFunctionConfig('order-processor', {
  timeout: 60,
  memorySize: 1024,
  environment: {
    DB_HOST: 'new-db.example.com',
    LOG_LEVEL: 'debug'
  }
});

Eliminando una Función

Elimina la función:

const deleteFunction = async (functionName, qualifier = null) => {
  const path = qualifier
    ? `/functions/${functionName}?Qualifier=${qualifier}`
    : `/functions/${functionName}`;

  await lambdaRequest(path, { method: 'DELETE' });
  console.log(`Función ${functionName} eliminada`);
};

Invocación de Funciones

Invocación Síncrona (Solicitud-Respuesta)

Invoca la función y espera la respuesta:

const invokeFunction = async (functionName, payload, qualifier = null) => {
  const path = qualifier
    ? `/functions/${functionName}/invocations?Qualifier=${qualifier}`
    : `/functions/${functionName}/invocations`;

  const response = await lambdaRequest(path, {
    method: 'POST',
    headers: {
      'X-Amz-Invocation-Type': 'RequestResponse', // Síncrona
      'X-Amz-Log-Type': 'Tail' // Incluir registros
    },
    body: payload
  });

  // Analizar respuesta
  const result = JSON.parse(Buffer.from(response.Payload).toString());
  const logs = Buffer.from(response.LogResult, 'base64').toString();

  return { result, logs };
};

// Uso
const { result, logs } = await invokeFunction('order-processor', {
  orderId: 'ORD-12345',
  customerId: 'CUST-67890',
  items: [
    { sku: 'PROD-001', quantity: 2 },
    { sku: 'PROD-002', quantity: 1 }
  ]
});

console.log(`Resultado: ${JSON.stringify(result)}`);
console.log(`Registros:\n${logs}`);

Invocación Asíncrona ("Disparar y Olvidar")

Invoca la función sin esperar:

const invokeAsync = async (functionName, payload) => {
  const response = await lambdaRequest(`/functions/${functionName}/invocations`, {
    method: 'POST',
    headers: {
      'X-Amz-Invocation-Type': 'Event', // Asíncrona
      'X-Amz-Log-Type': 'None'
    },
    body: payload
  });

  return {
    statusCode: response.StatusCode,
    executionId: response['X-Amz-Execution-Id']
  };
};

// Uso - activar procesamiento asíncrono
const result = await invokeAsync('email-sender', {
  to: 'customer@example.com',
  template: 'order-confirmation',
  data: { orderId: 'ORD-12345' }
});

console.log(`ID de invocación asíncrona: ${result.executionId}`);

Invocación de Prueba (Dry Run)

Prueba los permisos sin ejecutar:

const dryRunInvocation = async (functionName) => {
  const response = await lambdaRequest(`/functions/${functionName}/invocations`, {
    method: 'POST',
    headers: {
      'X-Amz-Invocation-Type': 'DryRun'
    }
  });

  return response;
};

// Uso - verificar permisos IAM
try {
  await dryRunInvocation('order-processor');
  console.log('Permisos de invocación OK');
} catch (error) {
  console.error('Permiso denegado:', error.message);
}

Tipos de Respuesta de Invocación

Tipo de Invocación Comportamiento Caso de Uso
RequestResponse Síncrona, espera el resultado Llamadas API, comandos CLI
Event Asíncrona, "disparar y olvidar" Procesamiento de eventos, notificaciones
DryRun Solo prueba de permisos Validación, depuración

Gestión de Versiones y Alias

Publicando Versiones

Crea una versión de función inmutable:

const publishVersion = async (functionName, description = null) => {
  const response = await lambdaRequest(`/functions/${functionName}/versions`, {
    method: 'POST',
    body: description ? { Description: description } : {}
  });

  return response;
};

// Uso
const version = await publishVersion('order-processor', 'v1.2.0 - Añadir cálculo de impuestos');
console.log(`Versión publicada: ${version.Version}`);

Creando Alias

Crea un puntero con nombre a la versión:

const createAlias = async (functionName, aliasName, version, description = null) => {
  const response = await lambdaRequest(`/functions/${functionName}/aliases`, {
    method: 'POST',
    body: {
      Name: aliasName,
      FunctionVersion: version,
      Description: description
    }
  });

  return response;
};

// Uso - Crear alias de producción
const prodAlias = await createAlias('order-processor', 'prod', '5', 'Versión de producción');
console.log(`ARN del alias: ${prodAlias.AliasArn}`);

Desplazamiento de Tráfico con Configuración de Enrutamiento

Desplaza gradualmente el tráfico a la nueva versión:

const updateAliasWithRouting = async (functionName, aliasName, routingConfig) => {
  const response = await lambdaRequest(`/functions/${functionName}/aliases/${aliasName}`, {
    method: 'PUT',
    body: {
      RoutingConfig: {
        AdditionalVersionWeights: routingConfig
      }
    }
  });

  return response;
};

// Uso - 10% del tráfico a la versión 6, 90% a la versión 5
await updateAliasWithRouting('order-processor', 'prod', {
  '6': 0.1
});

// Después de la validación, desplazar al 100%
await updateAliasWithRouting('order-processor', 'prod', {});

Casos de Uso de Alias

Alias Versión Propósito
dev $LATEST Pruebas de desarrollo
staging Última probada Validación QA
prod Versión estable Tráfico de producción
blue Producción actual Despliegues azul-verde
green Nueva versión Despliegues azul-verde

Mapeo de Fuentes de Eventos

Creando un Disparador SQS

Conecta una cola SQS a Lambda:

const createSQSEventSource = async (functionName, queueArn, batchSize = 10) => {
  const response = await lambdaRequest('/event-source-mappings', {
    method: 'POST',
    body: {
      EventSourceArn: queueArn,
      FunctionName: functionName,
      BatchSize: batchSize,
      Enabled: true
    }
  });

  return response;
};

// Uso
const mapping = await createSQSEventSource(
  'order-processor',
  'arn:aws:sqs:us-east-1:123456789012:orders-queue',
  10
);

console.log(`Fuente de eventos creada: ${mapping.UUID}`);

Creando un Disparador de Flujo DynamoDB

Conecta un flujo de DynamoDB a Lambda:

const createDynamoDBEventSource = async (functionName, streamArn, startingPosition = 'LATEST') => {
  const response = await lambdaRequest('/event-source-mappings', {
    method: 'POST',
    body: {
      EventSourceArn: streamArn,
      FunctionName: functionName,
      StartingPosition: startingPosition,
      BatchSize: 100,
      BisectBatchOnFunctionError: true,
      MaximumRetryAttempts: 3
    }
  });

  return response;
};

// Uso
await createDynamoDBEventSource(
  'user-analytics',
  'arn:aws:dynamodb:us-east-1:123456789012:table/Users/stream/2026-03-25T00:00:00.000'
);

Tipos de Fuentes de Eventos

Fuente Caso de Uso Soporte de Lotes
SQS Colas de mensajes Sí (1-10)
Kinesis Flujos en tiempo real Sí (1-10,000)
DynamoDB Streams Cambios en la base de datos Sí (1-1,000)
S3 Eventos de objeto No (1 por evento)
EventBridge Enrutamiento de eventos
API Gateway APIs HTTP No
Schedule Tareas programadas (cron jobs) No

Gestión de Capas

Creando una Capa

Empaqueta código/dependencias compartidos:

const createLayer = async (layerName, layerConfig) => {
  const response = await lambdaRequest('/layers', {
    method: 'POST',
    body: {
      LayerName: layerName,
      Description: layerConfig.description,
      CompatibleRuntimes: layerConfig.runtimes,
      Content: {
        S3Bucket: layerConfig.s3Bucket,
        S3Key: layerConfig.s3Key
      }
    }
  });

  return response;
};

// Uso
const layer = await createLayer('shared-utils', {
  description: 'Utilidades y dependencias compartidas',
  runtimes: ['nodejs20.x', 'nodejs18.x'],
  s3Bucket: 'my-layers-bucket',
  s3Key: 'shared-utils/v1.zip'
});

console.log(`ARN de la capa: ${layer.LayerArn}`);

Usando Capas en Funciones

Adjunta capas a la función:

const createFunctionWithLayers = async (functionConfig) => {
  const response = await lambdaRequest('/functions', {
    method: 'POST',
    body: {
      FunctionName: functionConfig.name,
      Runtime: functionConfig.runtime,
      Role: functionConfig.roleArn,
      Handler: functionConfig.handler,
      Code: {
        S3Bucket: functionConfig.s3Bucket,
        S3Key: functionConfig.s3Key
      },
      Layers: functionConfig.layers // Array de ARNs de capa
    }
  });

  return response;
};

// Uso
await createFunctionWithLayers({
  name: 'api-handler',
  roleArn: 'arn:aws:iam::123456789012:role/lambda-execution-role',
  handler: 'index.handler',
  runtime: 'nodejs20.x',
  s3Bucket: 'my-deployments-bucket',
  s3Key: 'api-handler/v1.0.0.zip',
  layers: [
    'arn:aws:lambda:us-east-1:123456789012:layer:shared-utils:1',
    'arn:aws:lambda:us-east-1:123456789012:layer:aws-sdk:3'
  ]
});

Concurrencia y Escalado

Estableciendo Concurrencia Reservada

Reserva capacidad para funciones críticas:

const putFunctionConcurrency = async (functionName, reservedConcurrentExecutions) => {
  const response = await lambdaRequest(`/functions/${functionName}/concurrency`, {
    method: 'PUT',
    body: {
      ReservedConcurrentExecutions: reservedConcurrentExecutions
    }
  });

  return response;
};

// Uso - Reservar 100 ejecuciones concurrentes
await putFunctionConcurrency('order-processor', 100);

Límites de Concurrencia de Cuenta

Tipo de Cuenta Límite Predeterminado Aumento Disponible
Capa Gratuita 1,000
Pago por uso 1,000
Empresarial 1,000+ Límites personalizados

Lista de Verificación para Implementación en Producción

Antes de implementar en producción:

Casos de Uso del Mundo Real

Backend de API

Una empresa SaaS construye una API REST sin servidor:

Implementación clave:

Pipeline de Procesamiento de Eventos

Una plataforma de comercio electrónico procesa pedidos:

Implementación clave:

Conclusión

La API de AWS Lambda proporciona capacidades completas de cómputo sin servidor. Puntos clave:

button

Sección de Preguntas Frecuentes

¿Cómo me autentico con la API de Lambda?

Utiliza credenciales de AWS IAM con la firma de la Versión 4. El SDK de AWS maneja la firma automáticamente.

¿Cuál es la diferencia entre invocación síncrona y asíncrona?

Síncrona (RequestResponse) espera la finalización de la función y devuelve los resultados. Asíncrona (Event) pone en cola la solicitud y regresa inmediatamente.

¿Cómo funcionan las versiones de Lambda?

Cada versión publicada es una instantánea inmutable de tu función. Utiliza alias para apuntar a versiones específicas y habilitar el desplazamiento de tráfico.

¿Qué son las Capas de Lambda?

Las capas empaquetan el código y las dependencias por separado del código de la función, permitiendo bibliotecas compartidas entre múltiples funciones.

¿Cómo reduzco los "arranques en frío"?

Utiliza concurrencia aprovisionada, paquetes de implementación más pequeños y lenguajes compilados (Go, Rust) para funciones críticas en cuanto a latencia.

¿Qué es la concurrencia reservada?

La concurrencia reservada garantiza ranuras de ejecución para funciones específicas, evitando problemas de "vecinos ruidosos".

¿Puedo activar Lambda desde S3?

Sí, configura notificaciones de eventos de S3 para invocar Lambda al crear/eliminar objetos.

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs