@aws-sdk v3
Use clientes modulares do AWS SDK v3 em Lambdas e contêineres Node.js - importe apenas o que você precisa, configure o middleware uma vez, reutilize clientes entre invocações.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
const s3 = new S3Client({ region: process.env.AWS_REGION });
export async function getObjectText(bucket: string, key: string) {
const res = await s3.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
return await res.Body?.transformToString();
}Quando usar isso: Qualquer chamada de serviço AWS a partir do Node 24 ou Lambda nodejs24.x. Não adicione aws-sdk v2.
Exemplo de Trabalho
// src/aws/clients.ts
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, GetCommand, PutCommand } from "@aws-sdk/lib-dynamodb";
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm";
import { NodeHttpHandler } from "@smithy/node-http-handler";
const requestHandler = new NodeHttpHandler({
connectionTimeout: 3_000,
requestTimeout: 10_000,
});
const ddbDoc = DynamoDBDocumentClient.from(
new DynamoDBClient({ maxAttempts: 3, requestHandler }),
{ marshallOptions: { removeUndefinedValues: true } }
);
const ssm = new SSMClient({ maxAttempts: 3 });
export async function getOrder(id: string) {
const res = await ddbDoc.send(
new GetCommand({ TableName: process.env.TABLE_NAME!, Key: { id } })
);
return res.Item;
}
export async function putOrder(item: Record<string, unknown>) {
await ddbDoc.send(
new PutCommand({ TableName: process.env.TABLE_NAME!, Item: item })
);
}
let cachedApiKey: string | undefined;
export async function getApiKey() {
if (cachedApiKey) return cachedApiKey;
const res = await ssm.send(
new GetParameterCommand({ Name: "/prod/api/KEY", WithDecryption: true })
);
cachedApiKey = res.Parameter?.Value;
return cachedApiKey!;
}// src/handler.ts
import type { APIGatewayProxyHandlerV2 } from "aws-lambda";
import { getOrder } from "./aws/clients.js";
export const handler: APIGatewayProxyHandlerV2 = async (event) => {
const id = event.pathParameters?.id!;
const order = await getOrder(id);
return {
statusCode: order ? 200 : 404,
body: JSON.stringify(order ?? { error: "not found" }),
};
};O que isso demonstra:
- Pacotes separados por serviço (
@aws-sdk/client-dynamodb,@aws-sdk/client-ssm) - Cliente de documento para mapas de atributos JS simples
- Timeouts do
NodeHttpHandlercompartilhados e reutilização do cliente com escopo de inicialização - Parâmetro SSM em cache no escopo do módulo entre invocações quentes
Mergulho Profundo
v2 vs v3
| Aspecto | AWS SDK v2 | AWS SDK v3 |
|---|---|---|
| Importar | import AWS from "aws-sdk" | @aws-sdk/client-s3 |
| Tamanho do pacote | SDK inteiro | Tree-shakeable por serviço |
| API | .promise() | client.send(new Command()) |
| Middleware | Limitado | Pilha de middleware Smithy |
Padrão de Comando
Toda operação é uma classe de comando:
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";
await sqs.send(new SendMessageCommand({
QueueUrl: process.env.QUEUE_URL!,
MessageBody: JSON.stringify({ orderId: "42" }),
}));Comandos são imutáveis; seguros para construir por solicitação.
Exemplo de Middleware
import { S3Client } from "@aws-sdk/client-s3";
const s3 = new S3Client({});
s3.middlewareStack.add(
(next) => async (args) => {
const start = Date.now();
const result = await next(args);
console.log(JSON.stringify({ awsCall: args.request?.hostname, ms: Date.now() - start }));
return result;
},
{ step: "finalizeRequest", name: "logLatency" }
);Use middleware para logging transversal, não para lógica de negócios.
Empacotamento do Runtime Lambda
Os runtimes Lambda Node.js 18+ incluem o AWS SDK for JavaScript v3. Você pode marcar @aws-sdk/* como external no esbuild para reduzir o tamanho dos pacotes de implantação. Fixe as versões do SDK no CI se você depender do comportamento do SDK empacotado no runtime.
Cadeia de Credenciais
Na Lambda, as credenciais vêm da função de execução automaticamente. O desenvolvimento local usa o arquivo de credenciais compartilhado ou SSO:
aws sso login --profile dev
AWS_PROFILE=dev npm run invoke:localArmadilhas
- Importar
@aws-sdk/client-s3elib-dynamodbinteiro sem uso - ainda melhor que o v2, mas audite as importações. Correção: um módulo cliente por domínio. - Novo cliente por solicitação - sobrecarga de handshake TLS. Correção: singleton no escopo do módulo.
maxAttemptsausente em redes instáveis - 503s transitórios falham invocações. Correção: o padrãomaxAttempts: 3geralmente é suficiente; ajuste por serviço.GetObjectgrande na memória - OOM em arquivos grandes. Correção: transmitaBodypara upload S3 ou disco.- Busca de parâmetro SSM a cada invocação - lento e com limite de taxa. Correção: cache com TTL no escopo do módulo.
- Incompatibilidade de região -
PermanentRedirectno S3. Correção: definaregionno cliente ou na variável de ambienteAWS_REGION.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| @aws-sdk v3 modular | Padrão para todas as chamadas AWS | Nunca para código novo |
| AWS SDK v2 | Apenas para manutenção legada | Novas Lambdas |
| AWS Data API | Aurora Serverless SQL sem VPC | Precisa de recursos PG completos |
| Construtos L2 do AWS CDK | Provisionamento de infraestrutura | Chamadas S3/GetObject em nível de aplicativo |
FAQs
Precisamos compactar `node_modules/@aws-sdk`?
Para Lambda, você pode externalizar o SDK se estiver usando um runtime gerenciado que o inclua. Para contêineres, instale apenas os clientes que você precisa na imagem.
Como eu pagino?
Use os auxiliares de paginação: import { paginateListObjectsV2 } from "@aws-sdk/client-s3" ou loop em NextToken nos comandos.
O v3 funciona com o modo estrito do TypeScript?
Sim. Os tipos de entrada de comando são gerados a partir de modelos Smithy.
E sobre `@aws-sdk/client-sts` AssumeRole?
Crie um cliente STS, assuma a função e passe as credenciais retornadas para os clientes de serviço através da configuração credentials para acesso entre contas.
Como isso se relaciona com o Secrets Manager?
Mesmo padrão: @aws-sdk/client-secrets-manager + GetSecretValueCommand, em cache na inicialização. Veja Secrets Managers.
Posso usar o v3 no Express no ECS?
Caminhos de código idênticos. A função de tarefa IAM substitui a função de execução Lambda para credenciais.
Relacionados
- Padrões de Manipulador Lambda - escopo de inicialização do cliente
- Mitigação de Cold Start - SDK externo em pacotes
- Secrets Managers - SSM e Secrets Manager
- Noções Básicas de Serverless - configuração da Lambda
- Melhores Práticas de Serverless - lista de verificação da seção
Versões da Stack: Esta página foi escrita para Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 e NestJS 11.