Noções Básicas de Serverless
10 exemplos para AWS Lambda com Node.js 24 - 7 básicos e 3 intermediários - além de quando escolher serverless vs. contêineres.
Busque em todas as páginas da documentação
10 exemplos para AWS Lambda com Node.js 24 - 7 básicos e 3 intermediários - além de quando escolher serverless vs. contêineres.
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 padrões de manipuladores e cold starts, veja Padrões de Manipuladores do Lambda e Mitigação de Cold Start.
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 em vez do estilo de callback em código novoAPIGatewayProxyHandlerV2import 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;
}env uma vez no cold start, não por solicitaçãoimport { 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 JavaScript purosimport 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 correlaçãoconsole.log com PII| Sinal | Prefira Lambda | Prefira contêineres (K8s/ECS) |
|---|---|---|
| Formato do tráfego | Esporádico, intermitente | Linha de base estável 24/7 |
| Duração da solicitação | Geralmente abaixo de 30s | Streams de longa duração |
| Conexões | HTTP sem estado | WebSockets, gRPC de longa duração |
| Modelo de operações | Nenhum cluster para gerenciar | Precisa de sidecars, rede personalizada |
| Sensibilidade a cold start | Pode tolerar 100-500ms | p99 inferior a 10ms necessário |
// 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 (fornecido pelo runtime ou camada)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) geralmente melhora o preço/desempenho para NodeTimeout a partir da latência p99 + chamadas downstreamimport 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 ou manipuladores dedicados em escala - veja serverless-express / aws-lambda-fastifynodejs24.x no Lambda para paridade com Node 24 LTS localmente. Alinhe o alvo do esbuild com node24.
Tráfego estável e baixa latência: Fargate ou K8s. Tráfego esporádico e operações mínimas: Lambda. Meça o custo em seu volume de solicitações.
Não. Compile ou empacote para JavaScript antes da implantação. Use esbuild em CI.
Use RDS Proxy ou Data API para Aurora Serverless v2. Não abra um novo pool PG por invocação sem proxy.
Apenas para acessar RDS/ElastiCache privados. A VPC adiciona latência de cold start de ENI; mitigue com Mitigação de Cold Start.
AWS Secrets Manager ou SSM Parameter Store, carregados na inicialização fora do caminho de acesso quente do manipulador. Veja Gerenciadores de Segredos.
Versões da Stack: Esta página foi escrita para Node.js 24.18.0 (LTS Ativo), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026