Upload de arquivos para AWS S3 utilizando Lambda Functions
Armazenar arquivos diretamente na aplicação pode gerar problemas de escalabilidade e custos desnecessários. Uma abordagem muito comum em arquiteturas serverless é utilizar o Amazon S3 em conjunto com AWS Lambda para realizar uploads de forma segura e eficiente.
O problema do upload tradicional
Em muitas aplicações, o upload é feito diretamente para o backend:
Cliente
↓
API
↓
Servidor
↓
Disco Local
Essa abordagem possui alguns problemas:
- Alto consumo do servidor;
- Escalabilidade limitada;
- Arquivos perdidos em caso de troca de instâncias;
- Maior custo de armazenamento.
Uma solução mais moderna é utilizar o Amazon S3.
O que é Amazon S3?
Amazon S3 (Simple Storage Service) é um serviço de armazenamento de objetos da AWS.
Ele permite armazenar:
- Imagens;
- PDFs;
- Vídeos;
- Arquivos CSV;
- Backups;
- Documentos em geral.
Além disso, oferece:
- Alta disponibilidade;
- Escalabilidade automática;
- Versionamento;
- Controle de acesso.
Arquitetura da solução
Uma arquitetura bastante comum utiliza Lambda Functions e URLs pré-assinadas.
Frontend
↓
Lambda Function
↓
URL Pré-assinada
↓
Amazon S3
Nesse fluxo:
- O frontend solicita uma URL para upload.
- A Lambda gera uma URL temporária.
- O cliente envia o arquivo diretamente para o S3.
- O backend não precisa processar o arquivo.
Por que utilizar URL pré-assinada?
Sem URL pré-assinada:
Frontend
↓
API
↓
Upload
↓
S3
Com URL pré-assinada:
Frontend
↓
Lambda
↓
URL
↓
S3
Isso reduz:
- Carga do servidor;
- Tempo de resposta;
- Custos de infraestrutura.
Criando a Lambda
Exemplo em Node.js:
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const client = new S3Client();
export const handler = async () => {
const command = new PutObjectCommand({
Bucket: "my-bucket",
Key: "images/photo.jpg"
});
const url = await getSignedUrl(
client,
command,
{ expiresIn: 300 }
);
return {
statusCode: 200,
body: JSON.stringify({ url })
};
};
A URL gerada ficará válida por 5 minutos.
Fazendo upload pelo frontend
Após receber a URL, basta enviar o arquivo:
await fetch(uploadUrl, {
method: "PUT",
body: file
});
O arquivo será armazenado diretamente no S3.
Estrutura recomendada
Uma organização simples dos arquivos pode ser:
bucket
│
├── images/
├── documents/
├── invoices/
├── avatars/
└── backups/
Isso facilita a organização e futuras políticas de acesso.
Utilizando metadados
Também é possível adicionar informações ao arquivo:
Metadata: {
userId: "10",
type: "invoice"
}
Esses dados podem ser úteis em consultas futuras.
Quando utilizar Lambda?
Lambda Functions são excelentes para:
- Gerar URLs pré-assinadas;
- Processar imagens;
- Criar miniaturas;
- Converter arquivos;
- Enviar notificações após upload.
Exemplo:
Upload
↓
S3
↓
Evento
↓
Lambda
↓
Thumbnail
Essa arquitetura é bastante utilizada em sistemas de imagens e vídeos.
Segurança
Algumas boas práticas:
Utilize tempo de expiração
Evite URLs permanentes.
Exemplo:
expiresIn: 300
Restrinja tipos de arquivos
Permita apenas formatos esperados:
- JPG
- PNG
Defina permissões mínimas
Utilize políticas IAM específicas para cada recurso.
Organize os arquivos por usuário
Por exemplo:
users/
10/
avatar.png
users/
20/
document.pdf
Isso facilita controle e auditoria.
Eventos no S3
Após o upload, o próprio S3 pode disparar eventos.
Exemplo:
Upload realizado
↓
S3 Event
↓
Lambda
↓
Processamento
Isso permite:
- Gerar thumbnails;
- Validar arquivos;
- Salvar registros no banco;
- Publicar eventos em filas.
Vantagens
Escalabilidade
O S3 cresce automaticamente conforme a demanda.
Menor carga na API
O backend não precisa receber os arquivos.
Baixo custo
Lambda e S3 possuem excelente relação custo-benefício.
Alta disponibilidade
Os arquivos ficam armazenados de forma segura e redundante.
Desvantagens
Maior complexidade inicial
É necessário configurar:
- S3;
- IAM;
- Lambda;
- Permissões.
Controle de acesso
A segurança deve ser bem planejada.
Casos de uso
Essa arquitetura é muito utilizada em:
- Upload de imagens;
- Sistemas de documentos;
- Plataformas de vídeo;
- Aplicativos mobile;
- E-commerce;
- Sistemas de RH.
Conclusão
Combinar Amazon S3 com Lambda Functions é uma excelente estratégia para construir soluções escaláveis e seguras para upload de arquivos.
Utilizando URLs pré-assinadas, é possível reduzir a carga da aplicação, melhorar a performance e aproveitar todos os benefícios da arquitetura serverless da AWS.
Saiba mais
- Amazon S3 Documentation
https://docs.aws.amazon.com/s3/ - AWS Lambda Documentation
https://docs.aws.amazon.com/lambda/ - Presigned URLs
https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html - AWS SDK JavaScript v3
https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/ - S3 Events
https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventNotifications.html - AWS IAM Best Practices
https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html