Conceptos básicos de Serverless
10 ejemplos para AWS Lambda con Node.js 24 (7 básicos y 3 intermedios), además de cuándo elegir serverless frente a contenedores.
Busca en todas las páginas de la documentación
10 ejemplos para AWS Lambda con Node.js 24 (7 básicos y 3 intermedios), además de cuándo elegir serverless frente a contenedores.
mkdir lambda-api && cd lambda-api
npm init -y
npm pkg set type=module
npm install @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb
npm install -D typescript@5.6 esbuild @types/aws-lambda @types/nodePara patrones de manejadores y arranques en frío, consulta Patrones de manejadores de Lambda y Mitigación de arranques en frío.
import type { APIGatewayProxyHandlerV2 } from "aws-lambda";
export const handler: APIGatewayProxyHandlerV2 = async (event) => {
return {
statusCode: 200,
headers: { "content-type": "application/json" },
body: JSON.stringify({ message: "hello", requestId: event.requestContext.requestId }),
};
};async sobre el estilo de callback en código nuevoAPIGatewayProxyHandlerV2import type { APIGatewayProxyHandlerV2 } from "aws-lambda";
export const handler: APIGatewayProxyHandlerV2 = async (event) => {
if (!event.body) {
return { statusCode: 400, body: JSON.stringify({ error: "missing body" }) };
}
const payload = JSON.parse(event.body) as { name?: string };
if (!payload.name) {
return { statusCode: 422, body: JSON.stringify({ error: "name required" }) };
}
return { statusCode: 201, body: JSON.stringify({ id: "1", name: payload.name }) };
};isBase64Encodedimport { z } from "zod";
const envSchema = z.object({
TABLE_NAME: z.string().min(1),
NODE_ENV: z.enum(["development", "production", "test"]).default("production"),
});
const env = envSchema.parse(process.env);
export function getTableName() {
return env.TABLE_NAME;
}import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, GetCommand } from "@aws-sdk/lib-dynamodb";
import type { APIGatewayProxyHandlerV2 } from "aws-lambda";
const client = DynamoDBDocumentClient.from(new DynamoDBClient({}));
export const handler: APIGatewayProxyHandlerV2 = async (event) => {
const id = event.pathParameters?.id;
const res = await client.send(
new GetCommand({ TableName: process.env.TABLE_NAME!, Key: { id } })
);
if (!res.Item) {
return { statusCode: 404, body: JSON.stringify({ error: "not found" }) };
}
return { statusCode: 200, body: JSON.stringify(res.Item) };
};@aws-sdk/lib-dynamodb para objetos JS planosimport type { SQSHandler } from "aws-lambda";
export const handler: SQSHandler = async (event) => {
for (const record of event.Records) {
const body = JSON.parse(record.body) as { orderId: string };
await processOrder(body.orderId);
}
};
async function processOrder(orderId: string) {
console.log(JSON.stringify({ event: "order_processed", orderId }));
}ReportBatchItemFailuresimport type { APIGatewayProxyHandlerV2 } from "aws-lambda";
export const handler: APIGatewayProxyHandlerV2 = async (event) => {
const requestId = event.requestContext.requestId;
console.log(JSON.stringify({
level: "info",
requestId,
path: event.rawPath,
method: event.requestContext.http.method,
}));
return { statusCode: 200, body: JSON.stringify({ ok: true }) };
};requestId para correlaciónconsole.log con PII| Señal | Preferir Lambda | Preferir contenedores (K8s/ECS) |
|---|---|---|
| Forma del tráfico | Con picos, intermitente | Línea base constante 24/7 |
| Duración de la solicitud | Típicamente menos de 30s | Streams de larga duración |
| Conexiones | HTTP sin estado | WebSockets, gRPC de larga duración |
| Modelo de operaciones | Sin clúster que gestionar | Necesita sidecars, redes personalizadas |
| Sensibilidad al arranque en frío | Puede tolerar 100-500ms | Se requiere p99 por debajo de 10ms |
// build.mjs
import * as esbuild from "esbuild";
await esbuild.build({
entryPoints: ["src/handler.ts"],
bundle: true,
platform: "node",
target: "node24",
outfile: "dist/handler.mjs",
format: "esm",
external: ["@aws-sdk/*"],
});{
"scripts": {
"build": "node build.mjs",
"zip": "cd dist && zip -r ../function.zip handler.mjs"
}
}@aws-sdk/* externo (proporcionado por el tiempo de ejecución o la capa)AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Resources:
ApiFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs24.x
Handler: handler.handler
MemorySize: 512
Timeout: 10
Architectures: [arm64]
Environment:
Variables:
TABLE_NAME: !Ref OrdersTable
Events:
Api:
Type: HttpApi
Properties:
Path: /orders/{id}
Method: GETarm64 (Graviton) a menudo mejora la relación precio/rendimiento para NodeTimeout a partir de la latencia p99 + llamadas descendentesimport express from "express";
import serverless from "serverless-http";
const app = express();
app.use(express.json());
app.get("/users", (_req, res) => res.json([]));
export const handler = serverless(app);@fastify/aws-lambda o manejadores dedicados a escala; consulta serverless-express / aws-lambda-fastifynodejs24.x en Lambda para paridad con Node 24 LTS localmente. Alinea el objetivo de esbuild con node24.
Tráfico constante y baja latencia: Fargate o K8s. Tráfico con picos y operaciones mínimas: Lambda. Mide el costo según tu volumen de solicitudes.
No. Compila o empaqueta a JavaScript antes de desplegar. Usa esbuild en CI.
Usa RDS Proxy o Data API para Aurora Serverless v2. No abras un nuevo pool de PG por invocación sin proxy.
Solo para acceder a RDS/ElastiCache privados. La VPC añade latencia de arranque en frío de ENI; mitígala con Mitigación de arranques en frío.
AWS Secrets Manager o SSM Parameter Store, cargados al inicio fuera de la ruta caliente del manejador. Consulta Administradores de secretos.
Versiones de la pila: Esta página fue escrita para Node.js 24.18.0 (LTS activa), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 y NestJS 11.
Revisado por Chris St. John·Última actualización: 16 jul 2026