DYNAMODB_PUT - Inserir Item no DynamoDB
O que é este Node?
O DYNAMODB_PUT é o node responsável por inserir ou sobrescrever itens em uma tabela do Amazon DynamoDB, o banco de dados NoSQL totalmente gerenciado da AWS.
Por que este Node existe?
O DynamoDB é um banco de dados NoSQL que armazena dados em formato chave-valor e documentos. O DYNAMODB_PUT existe para:
- Persistência de Dados: Salvar dados estruturados de forma rápida e escalável
- Sobrescrita Condicional: Inserir itens apenas se certas condições forem atendidas
- Atomicidade: Garantir que a operação seja completa ou não aconteça
- Integração AWS: Aproveitar a infraestrutura global da AWS com baixa latência
Como funciona internamente?
Quando o DYNAMODB_PUT é executado, o sistema:
- Autentica: Valida as credenciais AWS (Access Key ID e Secret Access Key)
- Conecta: Estabelece conexão com o DynamoDB na região especificada
- Valida: Verifica se a tabela existe e se o item tem as chaves obrigatórias
- Avalia Condição: Se houver ConditionExpression, avalia se a condição é verdadeira
- Se condição falha: Retorna erro sem inserir o item
- Se condição passa ou não existe: Insere/sobrescreve o item na tabela
- Retorna: Confirma sucesso da operação
Código interno (aws-executors.service.ts:292-301):
case 'putItem':
await dynamodb.put({
TableName: data.tableName,
Item: data.item,
ConditionExpression: data.conditionExpression,
}).promise();
return {
success: true,
message: 'Item inserted successfully',
};
Quando você DEVE usar este Node?
Use DYNAMODB_PUT sempre que precisar de armazenar dados no DynamoDB:
Casos de uso
- Salvar perfil de usuário: "Armazenar dados coletados de um cadastro no DynamoDB"
- Cache de sessões: "Guardar informações temporárias de sessão com TTL"
- Logs de eventos: "Registrar cada interação do usuário para análise posterior"
- Inventário: "Atualizar quantidade de produtos em estoque"
Quando NÃO usar DYNAMODB_PUT
- Dados relacionais complexos: Use MYSQL_QUERY ou POSTGRES_QUERY ao invés
- Buscar dados: Use DYNAMODB_GET ou DYNAMODB_QUERY ao invés
- Atualizar parcialmente: Use DYNAMODB_UPDATE ao invés (mais eficiente)
- Múltiplas tabelas com transação: Use BatchWriteItem da AWS ao invés
Parâmetros Detalhados
accessKeyId (string, obrigatório)
O que é: Chave de acesso da AWS para autenticação. Obtida no Console IAM da AWS.
Padrão: Nenhum (sempre obrigatório)
Flow completo para testar:
{
"name": "Teste DynamoDB Put - Access Key ID",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Solicitar Access Key",
"parameters": {
"message": "Digite seu Access Key ID da AWS:",
"variableName": "aws_access_key"
}
}
},
{
"id": "dynamodb_1",
"type": "dynamodb_put",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Inserir Teste",
"parameters": {
"accessKeyId": "{{aws_access_key}}",
"secretAccessKey": "sua-secret-key-aqui",
"region": "us-east-1",
"operation": "putItem",
"tableName": "TesteTabela",
"item": {
"id": "teste123",
"nome": "Item de Teste"
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Item inserido com sucesso no DynamoDB!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "dynamodb_1" },
{ "source": "dynamodb_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Digite qualquer texto quando solicitado. Se o Access Key for inválido, você verá erro de autenticação AWS.
secretAccessKey (string, obrigatório)
O que é: Chave secreta da AWS, usada junto com o Access Key ID para autenticação. NUNCA compartilhe publicamente.
Padrão: Nenhum (sempre obrigatório)
Flow completo para testar:
{
"name": "Teste DynamoDB Put - Secret Access Key",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Solicitar Secret Key",
"parameters": {
"message": "Digite sua Secret Access Key da AWS:",
"variableName": "aws_secret_key"
}
}
},
{
"id": "dynamodb_1",
"type": "dynamodb_put",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Inserir com Secret Key",
"parameters": {
"accessKeyId": "seu-access-key-aqui",
"secretAccessKey": "{{aws_secret_key}}",
"region": "us-east-1",
"operation": "putItem",
"tableName": "TesteTabela",
"item": {
"id": "teste456",
"dados": "Teste Secret Key"
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Autenticação bem-sucedida! Item inserido."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "dynamodb_1" },
{ "source": "dynamodb_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: A Secret Key deve corresponder ao Access Key ID. Credenciais incorretas resultarão em erro.
region (string, obrigatório)
O que é: Região AWS onde sua tabela DynamoDB está hospedada. Exemplos: "us-east-1", "sa-east-1", "eu-west-1".
Padrão: Nenhum (sempre obrigatório)
Flow completo para testar:
{
"name": "Teste DynamoDB Put - Region",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "switch_1",
"type": "switch",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Escolher Região",
"parameters": {
"message": "Escolha a região AWS:\n1️⃣ us-east-1 (N. Virginia)\n2️⃣ sa-east-1 (São Paulo)\n3️⃣ eu-west-1 (Irlanda)",
"cases": [
{ "value": "1", "label": "US East" },
{ "value": "2", "label": "SA East" },
{ "value": "3", "label": "EU West" }
]
}
}
},
{
"id": "dynamodb_1",
"type": "dynamodb_put",
"position": { "x": 500, "y": 50 },
"data": {
"label": "Inserir US",
"parameters": {
"accessKeyId": "seu-access-key",
"secretAccessKey": "sua-secret-key",
"region": "us-east-1",
"operation": "putItem",
"tableName": "TesteTabela",
"item": { "id": "us1", "regiao": "US East 1" }
}
}
},
{
"id": "dynamodb_2",
"type": "dynamodb_put",
"position": { "x": 500, "y": 150 },
"data": {
"label": "Inserir SA",
"parameters": {
"accessKeyId": "seu-access-key",
"secretAccessKey": "sua-secret-key",
"region": "sa-east-1",
"operation": "putItem",
"tableName": "TesteTabela",
"item": { "id": "sa1", "regiao": "SA East 1" }
}
}
},
{
"id": "dynamodb_3",
"type": "dynamodb_put",
"position": { "x": 500, "y": 250 },
"data": {
"label": "Inserir EU",
"parameters": {
"accessKeyId": "seu-access-key",
"secretAccessKey": "sua-secret-key",
"region": "eu-west-1",
"operation": "putItem",
"tableName": "TesteTabela",
"item": { "id": "eu1", "regiao": "EU West 1" }
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 150 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Item inserido na região selecionada!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 150 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "switch_1" },
{ "source": "switch_1", "target": "dynamodb_1", "label": "1" },
{ "source": "switch_1", "target": "dynamodb_2", "label": "2" },
{ "source": "switch_1", "target": "dynamodb_3", "label": "3" },
{ "source": "dynamodb_1", "target": "message_1" },
{ "source": "dynamodb_2", "target": "message_1" },
{ "source": "dynamodb_3", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Escolha uma opção. A região deve corresponder à localização da sua tabela DynamoDB.
tableName (string, obrigatório)
O que é: Nome da tabela DynamoDB onde o item será inserido. A tabela deve existir previamente.
Padrão: Nenhum (sempre obrigatório)
Flow completo para testar:
{
"name": "Teste DynamoDB Put - Table Name",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Nome da Tabela",
"parameters": {
"message": "Digite o nome da tabela DynamoDB:",
"variableName": "table_name"
}
}
},
{
"id": "dynamodb_1",
"type": "dynamodb_put",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Inserir na Tabela",
"parameters": {
"accessKeyId": "seu-access-key",
"secretAccessKey": "sua-secret-key",
"region": "us-east-1",
"operation": "putItem",
"tableName": "{{table_name}}",
"item": {
"id": "teste789",
"timestamp": "2025-10-12T10:00:00Z"
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Item inserido na tabela: {{table_name}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "dynamodb_1" },
{ "source": "dynamodb_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Digite um nome de tabela existente. Se a tabela não existir, verá erro "ResourceNotFoundException".
item (object, obrigatório)
O que é: Objeto JSON contendo os dados a serem inseridos. DEVE incluir a Partition Key (e Sort Key, se aplicável) definidas na tabela.
Padrão: Nenhum (sempre obrigatório)
Flow completo para testar:
{
"name": "Teste DynamoDB Put - Item",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Nome do Usuário",
"parameters": {
"message": "Digite seu nome:",
"variableName": "user_name"
}
}
},
{
"id": "email_1",
"type": "email",
"position": { "x": 300, "y": 200 },
"data": {
"label": "Email do Usuário",
"parameters": {
"message": "Digite seu email:",
"variableName": "user_email"
}
}
},
{
"id": "dynamodb_1",
"type": "dynamodb_put",
"position": { "x": 500, "y": 150 },
"data": {
"label": "Salvar Usuário",
"parameters": {
"accessKeyId": "seu-access-key",
"secretAccessKey": "sua-secret-key",
"region": "us-east-1",
"operation": "putItem",
"tableName": "Usuarios",
"item": {
"userId": "{{user_email}}",
"nome": "{{user_name}}",
"email": "{{user_email}}",
"dataCriacao": "2025-10-12T10:00:00Z",
"ativo": true,
"pontos": 0
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 150 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "Usuário {{user_name}} cadastrado com sucesso!\nEmail: {{user_email}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 150 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "email_1" },
{ "source": "email_1", "target": "dynamodb_1" },
{ "source": "dynamodb_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Digite nome e email. O item será inserido com todos os campos especificados.
conditionExpression (string, opcional)
O que é: Expressão condicional que deve ser verdadeira para o item ser inserido. Usado para evitar sobrescrever dados existentes.
Padrão: Nenhum (inserção sempre acontece se omitido)
Flow completo para testar:
{
"name": "Teste DynamoDB Put - Condition Expression",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 300, "y": 100 },
"data": {
"label": "ID do Produto",
"parameters": {
"message": "Digite o ID do produto:",
"variableName": "product_id"
}
}
},
{
"id": "dynamodb_1",
"type": "dynamodb_put",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Inserir se Não Existir",
"parameters": {
"accessKeyId": "seu-access-key",
"secretAccessKey": "sua-secret-key",
"region": "us-east-1",
"operation": "putItem",
"tableName": "Produtos",
"item": {
"productId": "{{product_id}}",
"nome": "Produto Novo",
"preco": 99.90,
"estoque": 100
},
"conditionExpression": "attribute_not_exists(productId)"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Sucesso",
"parameters": {
"message": "Produto {{product_id}} criado com sucesso!"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 700, "y": 200 },
"data": {
"label": "Erro",
"parameters": {
"message": "❌ Produto {{product_id}} já existe! Não foi possível criar."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "dynamodb_1" },
{ "source": "dynamodb_1", "target": "message_1", "label": "success" },
{ "source": "dynamodb_1", "target": "message_2", "label": "error" },
{ "source": "message_1", "target": "end_1" },
{ "source": "message_2", "target": "end_1" }
]
}
Teste: Digite um ID. Na primeira vez, insere com sucesso. Na segunda tentativa com mesmo ID, falha devido à condição.
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| accessKeyId | string | Sim | Chave de acesso AWS (IAM) |
| secretAccessKey | string | Sim | Chave secreta AWS |
| region | string | Sim | Região AWS (ex: us-east-1, sa-east-1) |
| operation | string | Sim | Tipo de operação (sempre "putItem") |
| tableName | string | Sim | Nome da tabela DynamoDB |
| item | object | Sim | Objeto com dados a inserir (deve ter Partition Key) |
| conditionExpression | string | Não | Condição para inserção (ex: attribute_not_exists(id)) |
Exemplo 1: Cadastro de Usuário Completo
Objetivo: Demonstrar inserção de perfil de usuário com todos os dados coletados via WhatsApp.
JSON para Importar
{
"name": "Cadastro Completo de Usuário - DynamoDB",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 300 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 250, "y": 300 },
"data": {
"label": "Boas-vindas",
"parameters": {
"message": "👋 Bem-vindo ao cadastro!\n\nVamos coletar seus dados para criar seu perfil."
}
}
},
{
"id": "input_1",
"type": "input",
"position": { "x": 400, "y": 300 },
"data": {
"label": "Nome",
"parameters": {
"message": "Qual é o seu nome completo?",
"variableName": "nome"
}
}
},
{
"id": "email_1",
"type": "email",
"position": { "x": 550, "y": 300 },
"data": {
"label": "Email",
"parameters": {
"message": "Digite seu melhor email:",
"variableName": "email"
}
}
},
{
"id": "phone_1",
"type": "phone",
"position": { "x": 700, "y": 300 },
"data": {
"label": "Telefone",
"parameters": {
"message": "Qual seu telefone com DDD?",
"variableName": "telefone"
}
}
},
{
"id": "date_1",
"type": "date",
"position": { "x": 850, "y": 300 },
"data": {
"label": "Data Nascimento",
"parameters": {
"message": "Digite sua data de nascimento (DD/MM/AAAA):",
"variableName": "dataNascimento"
}
}
},
{
"id": "dynamodb_1",
"type": "dynamodb_put",
"position": { "x": 1000, "y": 300 },
"data": {
"label": "Salvar no DynamoDB",
"parameters": {
"accessKeyId": "AKIAIOSFODNN7EXAMPLE",
"secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"region": "sa-east-1",
"operation": "putItem",
"tableName": "UsuariosCadastro",
"item": {
"userId": "{{email}}",
"nome": "{{nome}}",
"email": "{{email}}",
"telefone": "{{telefone}}",
"dataNascimento": "{{dataNascimento}}",
"dataCadastro": "2025-10-12T10:30:00Z",
"status": "ativo",
"origem": "whatsapp"
},
"conditionExpression": "attribute_not_exists(userId)"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1150, "y": 300 },
"data": {
"label": "Sucesso",
"parameters": {
"message": "✅ Cadastro realizado com sucesso!\n\n📝 Seus dados:\n👤 Nome: {{nome}}\n📧 Email: {{email}}\n📱 Telefone: {{telefone}}\n🎂 Nascimento: {{dataNascimento}}\n\nBem-vindo ao sistema!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1300, "y": 300 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "input_1" },
{ "source": "input_1", "target": "email_1" },
{ "source": "email_1", "target": "phone_1" },
{ "source": "phone_1", "target": "date_1" },
{ "source": "date_1", "target": "dynamodb_1" },
{ "source": "dynamodb_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: 👋 Bem-vindo ao cadastro!
Vamos coletar seus dados para criar seu perfil.
Sistema: Qual é o seu nome completo?
Usuário: José Roberto Silva
Sistema: Digite seu melhor email:
Usuário: jose@example.com
Sistema: Qual seu telefone com DDD?
Usuário: (11) 98765-4321
Sistema: Digite sua data de nascimento (DD/MM/AAAA):
Usuário: 15/03/1990
Sistema: ✅ Cadastro realizado com sucesso!
📝 Seus dados:
👤 Nome: José Roberto Silva
📧 Email: jose@example.com
📱 Telefone: (11) 98765-4321
🎂 Nascimento: 15/03/1990
Bem-vindo ao sistema!
Exemplo 2: Sistema de Pedidos com Prevenção de Duplicatas
Objetivo: Demonstrar uso de conditionExpression para evitar pedidos duplicados.
JSON para Importar
{
"name": "Registro de Pedido sem Duplicatas",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 200 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 250, "y": 200 },
"data": {
"label": "Iniciar Pedido",
"parameters": {
"message": "🛍️ Bem-vindo à loja!\n\nVamos criar seu pedido."
}
}
},
{
"id": "input_1",
"type": "input",
"position": { "x": 400, "y": 200 },
"data": {
"label": "Código Produto",
"parameters": {
"message": "Digite o código do produto:",
"variableName": "produto_codigo"
}
}
},
{
"id": "number_1",
"type": "number",
"position": { "x": 550, "y": 200 },
"data": {
"label": "Quantidade",
"parameters": {
"message": "Quantas unidades deseja?",
"variableName": "quantidade"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 700, "y": 200 },
"data": {
"label": "Gerar ID Pedido",
"parameters": {
"variableName": "pedido_id",
"value": "PED-{{produto_codigo}}-{{timestamp}}"
}
}
},
{
"id": "dynamodb_1",
"type": "dynamodb_put",
"position": { "x": 850, "y": 200 },
"data": {
"label": "Criar Pedido",
"parameters": {
"accessKeyId": "AKIAIOSFODNN7EXAMPLE",
"secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"region": "us-east-1",
"operation": "putItem",
"tableName": "Pedidos",
"item": {
"pedidoId": "{{pedido_id}}",
"produtoCodigo": "{{produto_codigo}}",
"quantidade": "{{quantidade}}",
"status": "pendente",
"dataCriacao": "2025-10-12T10:00:00Z",
"valorUnitario": 49.90,
"valorTotal": 0
},
"conditionExpression": "attribute_not_exists(pedidoId)"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1000, "y": 150 },
"data": {
"label": "Pedido Criado",
"parameters": {
"message": "✅ Pedido criado!\n\n🆔 ID: {{pedido_id}}\n📦 Produto: {{produto_codigo}}\n🔢 Quantidade: {{quantidade}}\n💰 Status: Pendente"
}
}
},
{
"id": "message_3",
"type": "message",
"position": { "x": 1000, "y": 250 },
"data": {
"label": "Pedido Duplicado",
"parameters": {
"message": "⚠️ Pedido {{pedido_id}} já existe!\n\nNão foi possível criar pedido duplicado."
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1150, "y": 200 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "input_1" },
{ "source": "input_1", "target": "number_1" },
{ "source": "number_1", "target": "variable_1" },
{ "source": "variable_1", "target": "dynamodb_1" },
{ "source": "dynamodb_1", "target": "message_2", "label": "success" },
{ "source": "dynamodb_1", "target": "message_3", "label": "error" },
{ "source": "message_2", "target": "end_1" },
{ "source": "message_3", "target": "end_1" }
]
}
Saída esperada:
Sistema: 🛍️ Bem-vindo à loja!
Vamos criar seu pedido.
Sistema: Digite o código do produto:
Usuário: PROD123
Sistema: Quantas unidades deseja?
Usuário: 5
Sistema: ✅ Pedido criado!
🆔 ID: PED-PROD123-1728734400
📦 Produto: PROD123
🔢 Quantidade: 5
💰 Status: Pendente
Exemplo 3: Cache de Sessão com TTL
Objetivo: Demonstrar inserção de dados temporários para cache de sessão de usuário.
JSON para Importar
{
"name": "Cache de Sessão DynamoDB com TTL",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 200 },
"data": { "label": "Início" }
},
{
"id": "input_1",
"type": "input",
"position": { "x": 250, "y": 200 },
"data": {
"label": "User ID",
"parameters": {
"message": "Digite seu ID de usuário:",
"variableName": "user_id"
}
}
},
{
"id": "input_2",
"type": "input",
"position": { "x": 400, "y": 200 },
"data": {
"label": "Dados Sessão",
"parameters": {
"message": "Digite os dados da sessão:",
"variableName": "session_data"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 550, "y": 200 },
"data": {
"label": "Calcular TTL",
"parameters": {
"variableName": "ttl_timestamp",
"value": "1728820800"
}
}
},
{
"id": "dynamodb_1",
"type": "dynamodb_put",
"position": { "x": 700, "y": 200 },
"data": {
"label": "Salvar Sessão",
"parameters": {
"accessKeyId": "AKIAIOSFODNN7EXAMPLE",
"secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"region": "us-east-1",
"operation": "putItem",
"tableName": "SessionCache",
"item": {
"sessionId": "{{user_id}}",
"userData": "{{session_data}}",
"createdAt": "2025-10-12T10:00:00Z",
"ttl": "{{ttl_timestamp}}",
"deviceInfo": "whatsapp-web",
"isActive": true
}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 850, "y": 200 },
"data": {
"label": "Confirmar",
"parameters": {
"message": "✅ Sessão criada!\n\n🆔 User: {{user_id}}\n📝 Dados: {{session_data}}\n⏰ Expira em: 24 horas\n\nSua sessão está ativa!"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1000, "y": 200 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "input_1" },
{ "source": "input_1", "target": "input_2" },
{ "source": "input_2", "target": "variable_1" },
{ "source": "variable_1", "target": "dynamodb_1" },
{ "source": "dynamodb_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Saída esperada:
Sistema: Digite seu ID de usuário:
Usuário: user_12345
Sistema: Digite os dados da sessão:
Usuário: token_abc123xyz
Sistema: ✅ Sessão criada!
🆔 User: user_12345
📝 Dados: token_abc123xyz
⏰ Expira em: 24 horas
Sua sessão está ativa!
Resposta do Node
{
"success": true,
"message": "Item inserted successfully"
}
Conceitos Importantes do DynamoDB
Partition Key e Sort Key
Partition Key (Chave de Partição):
- Campo obrigatório que determina em qual partição física o item será armazenado
- Deve ser único (se não houver Sort Key) ou combinado com Sort Key para unicidade
- Exemplo: userId, email, productId
Sort Key (Chave de Ordenação):
- Campo opcional que permite múltiplos itens com mesma Partition Key
- Itens são ordenados automaticamente pela Sort Key
- Exemplo: timestamp, orderId, version
Exemplo de estrutura:
Tabela: Pedidos
Partition Key: userId (string)
Sort Key: pedidoId (string)
Item 1: userId="user123", pedidoId="PED001", valor=100
Item 2: userId="user123", pedidoId="PED002", valor=200
Item 3: userId="user456", pedidoId="PED001", valor=150
Condition Expressions (Expressões Condicionais)
Permitem controlar quando um item pode ser inserido:
Expressões comuns:
- attribute_not_exists(id) - Insere apenas se o atributo "id" não existir (previne sobrescrita)
- attribute_exists(email) - Insere apenas se o atributo "email" já existir
- #status = :active - Insere apenas se status for "active" (requer ExpressionAttributeNames e Values)
Quando usar:
- Prevenir duplicatas: attribute_not_exists(primaryKey)
- Garantir estado: #count < :maxValue
- Validação de negócio: #stock >= :quantity
Boas Práticas
✅ SIM:
- Use
attribute_not_exists()para prevenir sobrescritas acidentais - Inclua timestamp de criação em todos os itens para auditoria
- Use nomes de atributos descritivos e consistentes (camelCase ou snake_case)
- Configure TTL (Time To Live) para dados temporários como sessões
- Sempre inclua Partition Key e Sort Key (se aplicável) no item
- Use variáveis do flow para dados dinâmicos ({{variavel}})
- Armazene credenciais AWS em variáveis de ambiente, nunca no código
❌ NÃO:
- Inserir itens sem Partition Key (causará erro)
- Usar valores hardcoded para dados que mudam (use variáveis)
- Expor credenciais AWS em logs ou mensagens
- Inserir dados sem validação prévia (valide email, phone, etc.)
- Usar PutItem para atualizar parcialmente (use UpdateItem ao invés)
- Criar itens com estruturas inconsistentes na mesma tabela
Dicas
💡 Dica 1: DynamoDB cobra por operação de escrita. Use UpdateItem ao invés de PutItem quando apenas alguns campos mudarem, pois PutItem sobrescreve o item inteiro.
💡 Dica 2: Configure TTL na tabela DynamoDB e adicione um campo ttl com timestamp Unix. Itens expiram automaticamente sem custo adicional.
💡 Dica 3: Use o email ou username como Partition Key para tabelas de usuários. Para tabelas com muitos registros por usuário, use Partition Key = userId e Sort Key = timestamp.
💡 Dica 4: Condition Expressions podem economizar dinheiro! Use attribute_not_exists() para evitar sobrescrever dados desnecessariamente.
💡 Dica 5: Para dados relacionais complexos (múltiplas tabelas com joins), considere usar MySQL ou PostgreSQL ao invés de DynamoDB.
Próximo Node
→ DYNAMODB_GET - Buscar item individual por chave → DYNAMODB_QUERY - Buscar múltiplos itens por Partition Key → DYNAMODB_UPDATE - Atualizar campos específicos de um item