Trabajo con S3 y almacenamiento en la nube en JavaScript (Node.js)
S3 (Simple Storage Service) es el estándar de facto para el almacenamiento de objetos en la nube. Independientemente de si utiliza Amazon S3, Yandex Object Storage, Mail.ru Cloud Storage o una solución local como MinIO, la API sigue siendo la misma. En este artículo, analizaremos cómo conectarse a almacenamiento compatible con S3 desde Node.js utilizando el AWS SDK v3 oficial.
¿Qué es S3 y para qué sirve?
S3 permite almacenar una cantidad ilimitada de archivos (objetos) en "cubos" (buckets). Cada objeto tiene una clave única (ruta) y metadatos. Los casos de uso principales son:
- Almacenamiento de archivos de usuario (avatares, documentos)
- Copias de seguridad de bases de datos y registros
- Archivos estáticos para aplicaciones web (imágenes, CSS, JS)
- Almacenamiento de archivos multimedia (video, audio)
Instalación y configuración de AWS SDK v3
A partir de la versión 3, AWS SDK se ha vuelto modular. Para trabajar con S3, basta con instalar un paquete:
npm install @aws-sdk/client-s3También necesitará variables de entorno con las claves de acceso. Lo mejor es almacenarlas en un archivo .env:
AWS_ACCESS_KEY_ID=your_access_keyAWS_SECRET_ACCESS_KEY=your_secret_keyAWS_REGION=ru-central1S3_ENDPOINT=https://storage.yandexcloud.netS3_BUCKET=my-bucketConexión a almacenamiento compatible con S3
Creemos un cliente S3 con un endpoint personalizado (para Yandex Object Storage, MinIO y otros):
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 y algunos almacenamientos compatibles con S3});
module.exports = s3Client;Operaciones principales con S3
1. Carga de archivo (PutObject)
Cargamos un archivo desde un búfer o flujo:
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 el tipo MIME correcto });
try { const response = await s3Client.send(command); console.log('Archivo cargado:', response.$metadata.httpStatusCode); return `https://storage.yandexcloud.net/${process.env.S3_BUCKET}/${key}`; } catch (err) { console.error('Error de carga:', err); }}2. Descarga de archivo (GetObject)
Obtenemos el objeto y lo guardamos 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('Archivo descargado:', destinationPath); } catch (err) { console.error('Error de descarga:', err); }}3. Obtención de lista de objetos (ListObjectsV2)
Útil para mostrar archivos en el 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 También en la biblioteca
Cliente HTTP para Go (Golang): mejores bibliotecas para trabajar con HTTP
Biblioteca estándar de Go (Golang): una visión completa
Jasypt Java: guía completa con ejemplos de cifrado
Cliente Redis para PHP: Predis y PhpRedis – conexión y ejemplos