Trabalhando com S3 e armazenamentos em nuvem em JavaScript (Node.js)
S3 (Simple Storage Service) é o padrão de facto para armazenamentos de objetos na nuvem. Independentemente de você usar Amazon S3, Yandex Object Storage, Mail.ru Cloud Storage ou uma solução local como MinIO, a API permanece a mesma. Neste artigo, vamos abordar como conectar-se a armazenamentos compatíveis com S3 a partir do Node.js usando o AWS SDK v3 oficial.
O que é S3 e para que serve?
S3 permite armazenar um número ilimitado de arquivos (objetos) em "buckets". Cada objeto tem uma chave única (caminho) e metadados. Os principais casos de uso são:
- Armazenamento de arquivos de usuário (avatars, documentos)
- Backups de bancos de dados e logs
- Arquivos estáticos para aplicações web (imagens, CSS, JS)
- Armazenamento de arquivos de mídia (vídeo, áudio)
Instalação e configuração do AWS SDK v3
A partir da versão 3, o AWS SDK tornou-se modular. Para trabalhar com S3, basta instalar um pacote:
npm install @aws-sdk/client-s3Você também precisará de variáveis de ambiente com as chaves de acesso. O melhor é armazená-las em um arquivo .env:
AWS_ACCESS_KEY_ID=your_access_keyAWS_SECRET_ACCESS_KEY=your_secret_keyAWS_REGION=ru-central1S3_ENDPOINT=https://storage.yandexcloud.netS3_BUCKET=my-bucketConectando a um armazenamento compatível com S3
Vamos criar um cliente S3 com endpoint personalizado (para Yandex Object Storage, MinIO e outros):
const { S3Client } = require('@aws-sdk/client-s3');require('dotenv').config();
const s3Client = new S3Client({ region: process.env.AWS_REGION, endpoint: process.env.S3_ENDPOINT, credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, }, forcePathStyle: true, // importante para MinIO e alguns armazenamentos compatíveis com S3});
module.exports = s3Client;Operações principais com S3
1. Upload de arquivo (PutObject)
Fazemos upload de um arquivo a partir de um buffer ou stream:
const { PutObjectCommand } = require('@aws-sdk/client-s3');const fs = require('fs');
async function uploadFile(filePath, key) { const fileContent = fs.readFileSync(filePath); const command = new PutObjectCommand({ Bucket: process.env.S3_BUCKET, Key: key, Body: fileContent, ContentType: 'image/png', // especifique o tipo MIME correto });
try { const response = await s3Client.send(command); console.log('Arquivo enviado:', response.$metadata.httpStatusCode); return `https://storage.yandexcloud.net/${process.env.S3_BUCKET}/${key}`; } catch (err) { console.error('Erro no upload:', err); }}2. Download de arquivo (GetObject)
Obtemos o objeto e o salvamos localmente:
const { GetObjectCommand } = require('@aws-sdk/client-s3');const fs = require('fs');const stream = require('stream');const { promisify } = require('util');const pipeline = promisify(stream.pipeline);
async function downloadFile(key, destinationPath) { const command = new GetObjectCommand({ Bucket: process.env.S3_BUCKET, Key: key, });
try { const response = await s3Client.send(command); const writeStream = fs.createWriteStream(destinationPath); await pipeline(response.Body, writeStream); console.log('Arquivo baixado:', destinationPath); } catch (err) { console.error('Erro no download:', err); }}3. Listagem de objetos (ListObjectsV2)
Útil para exibir arquivos no bucket:
const { ListObjectsV2Command } = require('@aws-sdk/client-s3');
async function listFiles(prefix = '') { const command = new ListObjectsV2Command({ Bucket: process.env.S3_BUCKET, Prefix: prefix, MaxKeys: 100, });
try { const response = await s3