Cómo utilizar Node.js V2
El « IBM Cloud® Object Storage » ( SDK for Node.js v2 ) ofrece funciones para sacar el máximo partido a IBM Cloud Object Storage.
IBM Cloud Object Storage SDK for Node.js v2 es una guía muy completa, con numerosas funciones y capacidades que superan el alcance y el espacio de esta guía. Para obtener documentación detallada sobre clases y métodos, consulta la documentación de referencia de la API de Node.js. Encontrará el código fuente en el repositorio GitHub.
Novedades de v2
El servicio IBM Cloud Object Storage ( SDK for Node.js ) ( v2 ) es una versión modernizada basada en la arquitectura del SDK de AWS ( v3 ), que aporta mejoras significativas:
- Arquitectura modular: importa solo los comandos y los clientes que necesites
- Diseño «Promise-first »: compatibilidad nativa con async/await y una gestión de errores más clara
- Paquetes de menor tamaño: los módulos que se pueden eliminar mediante «tree-shake» reducen el tamaño de la aplicación
- JavaScript moderno: aprovecha las funciones de ES6+ y es compatible con TypeScript
- Pila de middleware: canalización extensible de solicitudes y respuestas
- Mejor gestión de errores: tipos de error estructurados con información detallada
Los desarrolladores que deseen migrar desde v1 pueden consultar la Guía de migración.
Obtención del SDK
La forma recomendada de instalar el sistema operativo « IBM » (COS) SDK for Node.js es utilizar el gestor de paquetes npm para Node.js. Solo tienes que escribir lo siguiente en una ventana de terminal:
npm install ibm-cos-sdk-v2
Requisitos previos
- Node.js Versión 18 o posterior: el SDK requiere como mínimo la versión 18 de « Node.js » o una posterior.
- Un ejemplo de IBM Cloud Object Storage
- Una clave API de IBM Cloud Identity and Access Management que tenga, como mínimo, permisos de «
Writer» - El ID de la instancia de COS con la que estás trabajando
- Punto final de adquisición de tokens
- Punto final de servicio
Estos valores se pueden consultar en la consola de IBM Cloud generando unas «credenciales de servicio».
Importación de paquetes
Una vez instalado el SDK, deberá importar los paquetes que necesite a sus aplicaciones de Node.js para poder utilizar el SDK, tal y como se muestra en el siguiente ejemplo:
CommonJS:
const { S3Client } = require('ibm-cos-sdk-v2');
const {
CreateBucketCommand,
ListBucketsCommand,
PutObjectCommand,
GetObjectCommand
} = require('ibm-cos-sdk-v2');
Módulos ES / TypeScript:
import { S3Client } from 'ibm-cos-sdk-v2';
import {
CreateBucketCommand,
ListBucketsCommand,
PutObjectCommand,
GetObjectCommand
} from 'ibm-cos-sdk-v2';
Referencias del SDK
Clases principales
- S3Client- Cliente principal para interactuar con IBM Cloud Object Storage
- Clases comando- Cada operación tiene una clase comando correspondiente (por ejemplo,
PutObjectCommand,GetObjectCommand)
Configuración
- S3Client constructor: crea un nuevo cliente de « S3 » con opciones de configuración
- región: establece la región del cliente
- punto final: establece el punto final del servicio URL
- credenciales- Establece las credenciales de autenticación
Creación de un cliente y obtención de las credenciales del servicio
Para conectarse a IBM Cloud Object Storage, se crea y se configura un cliente proporcionando información de credenciales (clave de API e ID de instancia de servicio). Estos valores también se pueden tomar automáticamente de un archivo de credenciales o de variables de entorno.
Puede encontrar las credenciales creando una credencial de servicio o a través de la CLI.
Uso de la autenticación IAM de IBM
El siguiente ejemplo muestra cómo crear un cliente mediante la autenticación IAM de IBM con una clave de API:
CommonJS:
const { S3Client } = require('ibm-cos-sdk-v2');
// Initialize client
const client = new S3Client({
endpoint: 'https://s3.us-south.cloud-object-storage.appdomain.cloud',
region: 'us-south',
credentials: {
apiKey: '<API_KEY>',
serviceInstanceId: '<SERVICE_INSTANCE_ID>'
}
});
TypeScript:
import { S3Client } from 'ibm-cos-sdk-v2';
const client = new S3Client({
endpoint: 'https://s3.us-south.cloud-object-storage.appdomain.cloud',
region: 'us-south',
credentials: {
apiKey: '<API_KEY>',
serviceInstanceId: '<SERVICE_INSTANCE_ID>'
}
});
Las opciones de configuración necesarias son:
endpoint- El punto final URL correspondiente a la región de tu depósito de COSregion- La región en la que se encuentra tu bucketcredentials.apiKey- Tu clave API de IBM Cloud con los permisos adecuadoscredentials.serviceInstanceId- El CRN (Cloud Resource Name) de tu instancia de COS
Ejemplos de código
En los siguientes ejemplos se da por hecho que ya has creado un cliente tal y como se indica en la sección anterior.
Creación de un grupo
const { CreateBucketCommand } = require('ibm-cos-sdk-v2');
const command = new CreateBucketCommand({
Bucket: 'my-new-bucket',
CreateBucketConfiguration: {
LocationConstraint: 'us-south-standard'
}
});
try {
const response = await client.send(command);
console.log('Bucket created successfully');
} catch (err) {
console.error('Error creating bucket:', err);
}
Lista de buckets disponibles
const { ListBucketsCommand } = require('ibm-cos-sdk-v2');
try {
const command = new ListBucketsCommand({});
const response = await client.send(command);
console.log('Buckets:');
if (response.Buckets && response.Buckets.length > 0) {
response.Buckets.forEach(bucket => {
console.log(` - ${bucket.Name} (created: ${bucket.CreationDate})`);
});
} else {
console.log(' No buckets found');
}
} catch (err) {
console.error('Failed to list buckets:', err);
}
Lista de buckets con información detallada
IBM Cloud Object Storage ofrece una operación de listado ampliada que devuelve información adicional sobre el bucket:
const { ListBucketsExtendedCommand } = require('ibm-cos-sdk-v2');
const command = new ListBucketsExtendedCommand({
IBMServiceInstanceId: '<SERVICE_INSTANCE_ID>',
Prefix: 'my-bucket-prefix',
MaxKeys: 100
});
try {
const response = await client.send(command);
console.log('Extended Bucket Information:');
if (response.Buckets && response.Buckets.length > 0) {
response.Buckets.forEach(bucket => {
console.log(` Bucket: ${bucket.Name}`);
console.log(` Location: ${bucket.LocationConstraint}`);
console.log(` Created: ${bucket.CreationDate}`);
});
} else {
console.log(' No buckets found');
}
} catch (err) {
console.error('Failed to list buckets:', err);
}
Obtener la ubicación de un bucket
const { GetBucketLocationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new GetBucketLocationCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`Bucket '${bucketName}' is located in: ${response.LocationConstraint}`);
} catch (err) {
console.error('Failed to get bucket location:', err);
}
Supresión de un grupo
const { DeleteBucketCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket-to-delete';
const command = new DeleteBucketCommand({
Bucket: bucketName
});
try {
await client.send(command);
console.log(`Bucket '${bucketName}' deleted successfully`);
} catch (err) {
console.error('Failed to delete bucket:', err);
}
Nota: Un bucket debe estar vacío para poder eliminarlo.
Subir un objeto a un depósito
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const content = 'Hello, IBM Cloud Object Storage!';
const command = new PutObjectCommand({
Bucket: bucketName,
Key: objectKey,
Body: content
});
try {
const response = await client.send(command);
console.log(`Object '${objectKey}' uploaded successfully`);
console.log(`ETag: ${response.ETag}`);
} catch (err) {
console.error('Failed to upload object:', err);
}
Descarga de un objeto de un depósito
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new GetObjectCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
// Convert stream to buffer
const chunks = [];
for await (const chunk of response.Body) {
chunks.push(chunk);
}
const buffer = Buffer.concat(chunks);
console.log(`Object '${objectKey}' downloaded successfully`);
console.log(`Content-Type: ${response.ContentType}`);
console.log(`Content-Length: ${response.ContentLength} bytes`);
console.log(`Size: ${buffer.length} bytes`);
} catch (err) {
console.error('Failed to download object:', err);
}
Listado de objetos en un grupo
const { ListObjectsV2Command } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListObjectsV2Command({
Bucket: bucketName,
MaxKeys: 1000
});
try {
const response = await client.send(command);
console.log(`Objects in bucket '${bucketName}':`);
if (response.Contents && response.Contents.length > 0) {
response.Contents.forEach(object => {
console.log(` - ${object.Key} (size: ${object.Size} bytes, modified: ${object.LastModified})`);
});
console.log(`\nTotal objects: ${response.Contents.length}`);
} else {
console.log(' No objects found');
}
} catch (err) {
console.error('Failed to list objects:', err);
}
Copiar un objeto
const { CopyObjectCommand } = require('ibm-cos-sdk-v2');
const sourceBucket = 'source-bucket';
const sourceKey = 'source-object.txt';
const destinationBucket = 'destination-bucket';
const destinationKey = 'destination-object.txt';
// CopySource format: source-bucket/source-key
const copySource = `${sourceBucket}/${sourceKey}`;
const command = new CopyObjectCommand({
Bucket: destinationBucket,
Key: destinationKey,
CopySource: copySource
});
try {
const response = await client.send(command);
console.log('Object copied successfully');
if (response.CopyObjectResult) {
console.log(`ETag: ${response.CopyObjectResult.ETag}`);
}
} catch (err) {
console.error('Failed to copy object:', err);
}
Supresión de un objeto
const { DeleteObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'object-to-delete.txt';
const command = new DeleteObjectCommand({
Bucket: bucketName,
Key: objectKey
});
try {
await client.send(command);
console.log(`Object '${objectKey}' deleted successfully`);
} catch (err) {
console.error('Failed to delete object:', err);
}
Supresión de varios objetos
const { DeleteObjectsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectsToDelete = [
'object1.txt',
'object2.txt',
'object3.txt'
];
// Build delete request
const objects = objectsToDelete.map(key => ({ Key: key }));
const command = new DeleteObjectsCommand({
Bucket: bucketName,
Delete: {
Objects: objects,
Quiet: false
}
});
try {
const response = await client.send(command);
console.log('Delete operation completed');
if (response.Deleted && response.Deleted.length > 0) {
console.log(`Successfully deleted ${response.Deleted.length} object(s):`);
response.Deleted.forEach(deleted => {
console.log(` - ${deleted.Key}`);
});
}
if (response.Errors && response.Errors.length > 0) {
console.log(`\nFailed to delete ${response.Errors.length} object(s):`);
response.Errors.forEach(error => {
console.log(` - ${error.Key}: ${error.Message}`);
});
}
} catch (err) {
console.error('Failed to delete objects:', err);
}
Obtener los metadatos de un objeto (HEAD)
const { HeadObjectCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new HeadObjectCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
console.log(`Object Metadata for '${objectKey}':`);
console.log(` Content-Type: ${response.ContentType}`);
console.log(` Content-Length: ${response.ContentLength} bytes`);
console.log(` ETag: ${response.ETag}`);
console.log(` Last-Modified: ${response.LastModified}`);
if (response.Metadata && Object.keys(response.Metadata).length > 0) {
console.log(' Custom Metadata:');
for (const [key, value] of Object.entries(response.Metadata)) {
console.log(` ${key}: ${value}`);
}
}
} catch (err) {
console.error('Failed to get object metadata:', err);
}
Utilización de cargas de varias partes
En el caso de los archivos de gran tamaño, la subida en varias partes ofrece un mayor rendimiento y la posibilidad de reanudar las subidas. Cada parte debe tener un tamaño mínimo de 5 MB (excepto la última).
Carga manual de varios archivos:
const {
CreateMultipartUploadCommand,
UploadPartCommand,
CompleteMultipartUploadCommand,
AbortMultipartUploadCommand
} = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'large-object.dat';
try {
// Step 1: Initiate multipart upload
const createCommand = new CreateMultipartUploadCommand({
Bucket: bucketName,
Key: objectKey
});
const createResponse = await client.send(createCommand);
const uploadId = createResponse.UploadId;
console.log(`Multipart upload initiated with ID: ${uploadId}`);
// Step 2: Upload parts (minimum 5MB per part except last)
const completedParts = [];
const minPartSize = 5 * 1024 * 1024; // 5MB
// Create sample parts
const parts = [
'A'.repeat(minPartSize),
'B'.repeat(minPartSize)
];
for (let i = 0; i < parts.length; i++) {
const partNumber = i + 1;
const uploadPartCommand = new UploadPartCommand({
Bucket: bucketName,
Key: objectKey,
PartNumber: partNumber,
UploadId: uploadId,
Body: parts[i]
});
try {
const uploadResponse = await client.send(uploadPartCommand);
completedParts.push({
ETag: uploadResponse.ETag,
PartNumber: partNumber
});
console.log(`Part ${partNumber} uploaded (ETag: ${uploadResponse.ETag})`);
} catch (err) {
// Abort multipart upload on error
const abortCommand = new AbortMultipartUploadCommand({
Bucket: bucketName,
Key: objectKey,
UploadId: uploadId
});
await client.send(abortCommand);
throw err;
}
}
// Step 3: Complete multipart upload
const completeCommand = new CompleteMultipartUploadCommand({
Bucket: bucketName,
Key: objectKey,
UploadId: uploadId,
MultipartUpload: {
Parts: completedParts
}
});
const completeResponse = await client.send(completeCommand);
console.log('Multipart upload completed successfully');
console.log(`Location: ${completeResponse.Location}`);
console.log(`ETag: ${completeResponse.ETag}`);
} catch (err) {
console.error('Failed to complete multipart upload:', err);
}
Uso del Gestor de subidas (recomendado):
Para facilitar las subidas en varias partes, utiliza el paquete « @ibm-cos/lib-storage »:
const { Upload } = require('@ibm-cos/lib-storage');
const { S3Client } = require('ibm-cos-sdk-v2');
const fs = require('fs');
const fileStream = fs.createReadStream('large-file.bin');
const upload = new Upload({
client: client,
params: {
Bucket: 'my-bucket',
Key: 'large-file.bin',
Body: fileStream
},
queueSize: 4, // Concurrent parts
partSize: 5 * 1024 * 1024, // 5MB parts
leavePartsOnError: false
});
// Track progress
upload.on('httpUploadProgress', (progress) => {
console.log('Upload progress:', progress);
});
try {
const result = await upload.done();
console.log('Upload completed:', result);
} catch (err) {
console.error('Upload failed:', err);
}
Listado de subidas multiparte
const { ListMultipartUploadsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListMultipartUploadsCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`In-progress multipart uploads in bucket '${bucketName}':`);
if (response.Uploads && response.Uploads.length > 0) {
response.Uploads.forEach(upload => {
console.log(` Key: ${upload.Key}`);
console.log(` Upload ID: ${upload.UploadId}`);
console.log(` Initiated: ${upload.Initiated}`);
});
} else {
console.log(' No in-progress uploads found');
}
} catch (err) {
console.error('Failed to list multipart uploads:', err);
}
Enumeración de las partes de una subida de varios archivos
Muestra todas las partes subidas de una subida de varias partes en curso. Útil para comprobar el progreso o recopilar ETags antes de completar la subida.
const { ListPartsCommand } = require('ibm-cos-sdk-v2');
const command = new ListPartsCommand({
Bucket: 'my-bucket',
Key: 'my-large-object',
UploadId: 'YOUR_UPLOAD_ID_HERE'
});
try {
const response = await client.send(command);
console.log('Parts listed successfully');
if (response.Parts && response.Parts.length > 0) {
response.Parts.forEach(p =>
console.log(' - Part', p.PartNumber, '| ETag:', p.ETag, '| Size:', p.Size, 'bytes')
);
} else {
console.log('No parts found.');
}
} catch (err) {
console.error('Error listing parts:', err);
}
Copiar una parte de un objeto existente
Carga una pieza copiándola de un objeto existente. Utiliza esto en lugar de subir bytes sin procesar cuando los datos de origen ya existan en COS.
const { UploadPartCopyCommand } = require('ibm-cos-sdk-v2');
const command = new UploadPartCopyCommand({
Bucket: 'my-bucket',
Key: 'my-large-object',
UploadId: 'YOUR_UPLOAD_ID_HERE',
PartNumber: 1,
CopySource: 'my-bucket/source-object-key'
});
try {
const response = await client.send(command);
console.log('Part copy uploaded successfully');
console.log('ETag:', response.CopyPartResult?.ETag);
} catch (err) {
console.error('Error uploading part copy:', err);
}
Configuración del ciclo de vida de un bucket
Las políticas de archivo te permiten trasladar automáticamente los objetos a clases de almacenamiento de archivo tras un periodo de tiempo determinado:
const { PutBucketLifecycleConfigurationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
// Configure lifecycle rule to expire objects after 30 days
const command = new PutBucketLifecycleConfigurationCommand({
Bucket: bucketName,
LifecycleConfiguration: {
Rules: [
{
Id: 'delete-old-logs',
Status: 'Enabled',
Filter: {
Prefix: 'logs/',
},
Expiration: {
Days: 30,
},
},
{
Id: 'cleanup-multipart-uploads',
Status: 'Enabled',
Filter: {
Prefix: '',
},
AbortIncompleteMultipartUpload: {
DaysAfterInitiation: 7,
},
},
]
}
});
try {
await client.send(command);
console.log(`Lifecycle configuration set for bucket '${bucketName}'`);
} catch (err) {
console.error('Failed to set lifecycle configuration:', err);
}
Obtener la configuración del ciclo de vida de un bucket
const { GetBucketLifecycleConfigurationCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new GetBucketLifecycleConfigurationCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`Lifecycle rules for bucket '${bucketName}':`);
if (response.Rules && response.Rules.length > 0) {
response.Rules.forEach(rule => {
console.log(` Rule ID: ${rule.ID}`);
console.log(` Status: ${rule.Status}`);
if (rule.Transitions && rule.Transitions.length > 0) {
rule.Transitions.forEach(transition => {
console.log(` Transition to ${transition.StorageClass} after ${transition.Days} days`);
});
}
});
} else {
console.log(' No lifecycle rules found');
}
} catch (err) {
console.error('Failed to get lifecycle configuration:', err);
}
Activación del control de versiones de los buckets
const { PutBucketVersioningCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new PutBucketVersioningCommand({
Bucket: bucketName,
VersioningConfiguration: {
// Valid values: 'Enabled' | 'Suspended'
Status: 'Enabled',
},
});
try {
await client.send(command);
console.log(`Versioning enabled for bucket '${bucketName}'`);
} catch (err) {
console.error('Failed to enable versioning:', err);
}
Listado de versiones de objetos
const { ListObjectVersionsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const command = new ListObjectVersionsCommand({
Bucket: bucketName
});
try {
const response = await client.send(command);
console.log(`Object versions in bucket '${bucketName}':`);
if (response.Versions && response.Versions.length > 0) {
response.Versions.forEach(version => {
console.log(` Key: ${version.Key}`);
console.log(` Version ID: ${version.VersionId}`);
console.log(` Is Latest: ${version.IsLatest}`);
console.log(` Last Modified: ${version.LastModified}`);
});
} else {
console.log(' No versions found');
}
} catch (err) {
console.error('Failed to list object versions:', err);
}
Configuración de « CORS »
const { PutBucketCorsCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
// Set CORS configuration
const command = new PutBucketCorsCommand({
Bucket: bucketName,
CORSConfiguration: {
CORSRules: [
{
AllowedHeaders: ['*'],
AllowedMethods: ['GET', 'PUT', 'POST', 'DELETE'],
AllowedOrigins: ['https://example.com'],
ExposeHeaders: ['ETag'],
MaxAgeSeconds: 3000
}
]
}
});
try {
await client.send(command);
console.log(`CORS configuration set for bucket '${bucketName}'`);
} catch (err) {
console.error('Failed to set CORS configuration:', err);
}
Configuración del etiquetado de objetos
const { PutObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
// Set object tags
const command = new PutObjectTaggingCommand({
Bucket: bucketName,
Key: objectKey,
Tagging: {
TagSet: [
{
Key: 'Department',
Value: 'Finance'
},
{
Key: 'Project',
Value: 'Q4-2024'
},
{
Key: 'Classification',
Value: 'Confidential'
}
]
}
});
try {
await client.send(command);
console.log(`Tags set for object '${objectKey}'`);
} catch (err) {
console.error('Failed to set object tags:', err);
}
Obtener etiquetas de objetos
const { GetObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-bucket';
const objectKey = 'my-object.txt';
const command = new GetObjectTaggingCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
console.log(`Tags for object '${objectKey}':`);
if (response.TagSet && response.TagSet.length > 0) {
response.TagSet.forEach(tag => {
console.log(` ${tag.Key}: ${tag.Value}`);
});
} else {
console.log(' No tags found');
}
} catch (err) {
console.error('Failed to get object tags:', err);
}
Restauración de un objeto archivado
Los objetos de las clases de almacenamiento de archivo deben restaurarse antes de poder acceder a ellos:
const command = new RestoreObjectCommand({
Bucket: bucketName,
Key: objectKey,
RestoreRequest: {
Days: 7,
GlacierJobParameters: {
Tier: 'Bulk',
},
},
});
try {
await client.send(command);
console.log('Object restore initiated successfully');
console.log(
'Retrieval time depends on storage class: Vault typically 1-5 hours, Cold Vault typically 5-12 hours.'
);
} catch (err) {
console.error('Failed to restore object:', err);
}
Nota: IBM Cloud Object Storage solo admite el nivel de recuperación Bulk para restaurar objetos de las clases de almacenamiento Vault y Cold Vault.
Configuración de la retención de objetos
Modo de gestión: Los usuarios con permisos específicos de IAM pueden eliminar versiones de objetos durante el periodo de retención.
Modo de cumplimiento: Ningún usuario puede eliminar versiones de objetos durante el periodo de retención.
const { PutObjectRetentionCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-protected-bucket';
const objectKey = 'important-document.pdf';
// Set retention until a specific date
const retainUntil = new Date();
retainUntil.setDate(retainUntil.getDate() + 30);
const command = new PutObjectRetentionCommand({
Bucket: bucketName,
Key: objectKey,
Retention: {
Mode: 'COMPLIANCE',
RetainUntilDate: retainUntil,
},
});
try {
await client.send(command);
console.log('Object retention set successfully');
console.log('RetainUntil:', retainUntil.toISOString());
} catch (err) {
console.error('Error:', err.message);
}
Obtener la retención de objetos
const { GetObjectRetentionCommand } = require('ibm-cos-sdk-v2');
const bucketName = 'my-protected-bucket';
const objectKey = 'important-document.pdf';
const command = new GetObjectRetentionCommand({
Bucket: bucketName,
Key: objectKey
});
try {
const response = await client.send(command);
console.log('Object retention retrieved successfully');
console.log('Mode:', response.Retention?.Mode);
console.log('RetainUntilDate:', response.Retention?.RetainUntilDate);
} catch (err) {
console.error('Error:', err.message);
}
Creación de un bucket con Object Lock ( S3 )
S3 Object Lock impide que los objetos se eliminen o se sobrescriban durante un periodo de retención fijo o de forma indefinida. Object Lock debe habilitarse en el momento de crear el bucket; no se puede añadir a un bucket ya existente.
Modo de gestión: Los usuarios con permisos específicos de IAM pueden eliminar versiones de objetos durante el periodo de retención.
Modo de cumplimiento: Ningún usuario puede eliminar versiones de objetos durante el periodo de retención.
Esta sección trata sobre Object Lock de S3-compatible. Para obtener información sobre la protección WORM específica de COS ( IBM ), consulte Configuración de la protección de buckets(WORM) y Gestión de retenciones legales.
const {
CreateBucketCommand,
PutObjectLockConfigurationCommand
} = require('ibm-cos-sdk-v2');
// Step 1: Create bucket with Object Lock enabled
const createCommand = new CreateBucketCommand({
Bucket: 'my-locked-bucket',
ObjectLockEnabledForBucket: true
});
try {
await client.send(createCommand);
console.log('Bucket created with Object Lock enabled');
} catch (err) {
console.error('Error creating bucket:', err.message);
}
// Step 2: Set default retention rule
const lockConfigCommand = new PutObjectLockConfigurationCommand({
Bucket: 'my-locked-bucket',
ObjectLockConfiguration: {
ObjectLockEnabled: 'Enabled',
Rule: {
DefaultRetention: {
Mode: 'GOVERNANCE',
Days: 30
}
}
}
});
try {
await client.send(lockConfigCommand);
console.log('Default Object Lock configuration set successfully');
} catch (err) {
console.error('Error setting lock config:', err.message);
}
Configuración de Object Lock
Establece o actualiza la regla de retención predeterminada que se aplica a cada nuevo objeto cargado en un depósito.
const { PutObjectLockConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectLockConfigurationCommand({
Bucket: 'my-object-lock-bucket',
ObjectLockConfiguration: {
ObjectLockEnabled: 'Enabled',
Rule: {
DefaultRetention: {
Mode: 'COMPLIANCE',
Days: 2
}
}
}
});
try {
await client.send(command);
console.log('Object lock configuration set successfully');
} catch (err) {
console.error('Error:', err.message);
}
Configuración de Object Lock
const { GetObjectLockConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectLockConfigurationCommand({
Bucket: 'my-object-lock-bucket'
});
try {
const response = await client.send(command);
console.log('Object lock configuration retrieved successfully');
console.log('ObjectLockEnabled:', response.ObjectLockConfiguration?.ObjectLockEnabled);
console.log('Rule:', JSON.stringify(response.ObjectLockConfiguration?.Rule, null, 2));
} catch (err) {
console.error('Error:', err.message);
}
Configuración de la retención legal de Object Lock en S3
Aplica o elimina una retención legal sobre un objeto. Mientras una retención legal esté activa, el objeto no se puede eliminar, independientemente de su periodo de conservación.
const { PutObjectLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectLegalHoldCommand({
Bucket: 'my-locked-bucket',
Key: 'my-file.txt',
LegalHold: {
Status: 'ON' // 'ON' or 'OFF'
}
});
try {
await client.send(command);
console.log('Legal hold set successfully');
} catch (err) {
console.error('Error:', err.message);
}
Cómo aplicar una retención legal a un Object Lock de S3
const { GetObjectLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectLegalHoldCommand({
Bucket: 'my-locked-bucket',
Key: 'my-file.txt'
});
try {
const response = await client.send(command);
console.log('Legal hold retrieved successfully');
console.log('Status:', response.LegalHold?.Status);
} catch (err) {
console.error('Error:', err.message);
}
Comprobación de si existe un bucket (HEAD)
const { HeadBucketCommand } = require('ibm-cos-sdk-v2');
const command = new HeadBucketCommand({
Bucket: 'my-bucket'
});
try {
await client.send(command);
console.log('Bucket exists');
} catch (err) {
if (err.name === 'NotFound') {
console.log('Bucket does not exist');
} else {
console.error('Error checking bucket:', err);
}
}
Carga en streaming desde un archivo
const fs = require('fs');
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const fileStream = fs.createReadStream('large-file.bin');
const command = new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'large-file.bin',
Body: fileStream
});
try {
const response = await client.send(command);
console.log('File uploaded successfully');
} catch (err) {
console.error('Error uploading file:', err);
}
Descarga en streaming a un archivo
const fs = require('fs');
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'large-file.bin'
});
try {
const response = await client.send(command);
const fileStream = fs.createWriteStream('downloaded-file.bin');
response.Body.pipe(fileStream);
await new Promise((resolve, reject) => {
fileStream.on('finish', resolve);
fileStream.on('error', reject);
response.Body.on('error', reject);
});
console.log('File downloaded successfully');
} catch (err) {
console.error('Error downloading file:', err);
}
Listado de todos los objetos con paginación
El SDK de v2 proporciona paginadores integrados para operaciones que devuelven resultados truncados.
Uso de un paginador (recomendado):
const { paginateListObjectsV2 } = require('ibm-cos-sdk-v2');
async function listAllObjects(bucket, prefix) {
const allObjects = [];
const paginator = paginateListObjectsV2(
{ client: client, pageSize: 1000 },
{ Bucket: bucket, Prefix: prefix }
);
try {
for await (const page of paginator) {
if (page.Contents) {
allObjects.push(...page.Contents);
}
}
console.log('Total objects:', allObjects.length);
return allObjects;
} catch (err) {
console.error('Error listing objects:', err);
throw err;
}
}
Paginación del manual:
const { ListObjectsV2Command } = require('ibm-cos-sdk-v2');
async function listAllObjects(bucket, prefix) {
const allObjects = [];
let continuationToken = undefined;
do {
const command = new ListObjectsV2Command({
Bucket: bucket,
Prefix: prefix,
ContinuationToken: continuationToken
});
const response = await client.send(command);
if (response.Contents) {
allObjects.push(...response.Contents);
}
continuationToken = response.NextContinuationToken;
} while (continuationToken);
console.log('Total objects:', allObjects.length);
return allObjects;
}
Generación de URL prefirmadas
Las URL prefirmadas permiten el acceso temporal y sin autenticación a los objetos. Instala primero el paquete presigner:
npm install @ibm-cos/s3-request-presigner
GET prefirmado URL (descargar):
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const { getSignedUrl } = require('@ibm-cos/s3-request-presigner');
const command = new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt'
});
try {
const url = await getSignedUrl(client, command, { expiresIn: 3600 });
console.log('Presigned URL:', url);
} catch (err) {
console.error('Error generating presigned URL:', err);
}
PUT prefirmado URL (subir):
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const { getSignedUrl } = require('@ibm-cos/s3-request-presigner');
const command = new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'upload-object.txt',
ContentType: 'text/plain'
});
try {
const url = await getSignedUrl(client, command, { expiresIn: 3600 });
console.log('Presigned PUT URL:', url);
} catch (err) {
console.error('Error generating presigned URL:', err);
}
Configuración de CORS
const { GetBucketCorsCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketCorsCommand({
Bucket: 'my-bucket'
});
try {
const response = await client.send(command);
console.log('CORS rules:', response.CORSRules);
} catch (err) {
console.error('Error getting CORS configuration:', err);
}
Eliminación de la configuración de CORS
const { DeleteBucketCorsCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketCorsCommand({
Bucket: 'my-bucket'
});
try {
await client.send(command);
console.log('Bucket CORS configuration deleted successfully');
} catch (err) {
console.error('Error deleting CORS:', err);
}
Carga de un objeto con metadatos personalizados
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt',
Body: 'content',
Metadata: {
'author': 'John Doe',
'department': 'Engineering'
}
});
try {
await client.send(command);
console.log('Object uploaded with metadata');
} catch (err) {
console.error('Error uploading object:', err);
}
Configuración del etiquetado de buckets
const { PutBucketTaggingCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketTaggingCommand({
Bucket: 'my-bucket',
Tagging: {
TagSet: [
{ Key: 'Environment', Value: 'Production' },
{ Key: 'Project', Value: 'WebApp' }
]
}
});
try {
await client.send(command);
console.log('Bucket tags updated');
} catch (err) {
console.error('Error updating bucket tags:', err);
}
Eliminación de una configuración del ciclo de vida de un bucket
const { DeleteBucketLifecycleCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketLifecycleCommand({
Bucket: 'my-bucket'
});
try {
await client.send(command);
console.log('Lifecycle configuration deleted successfully');
} catch (err) {
console.error('Error deleting lifecycle:', err);
}
Configuración de la lista de control de acceso (ACL) de un bucket
const { PutBucketAclCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketAclCommand({
Bucket: 'my-bucket',
ACL: 'public-read'
});
try {
await client.send(command);
console.log('Bucket ACL updated');
} catch (err) {
console.error('Error updating bucket ACL:', err);
}
Obtener la lista de controles de acceso (ACL) de un bucket
const { GetBucketAclCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketAclCommand({
Bucket: 'my-bucket'
});
try {
const response = await client.send(command);
console.log('Bucket ACL retrieved successfully');
console.log('Owner:', response.Owner);
console.log('Grants:', response.Grants);
} catch (err) {
console.error('Error getting bucket ACL:', err);
}
Configuración de la ACL de un objeto
const { PutObjectAclCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectAclCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt',
ACL: 'public-read'
});
try {
await client.send(command);
console.log('Object ACL updated');
} catch (err) {
console.error('Error updating object ACL:', err);
}
Obtener la ACL de un objeto
const { GetObjectAclCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectAclCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt'
});
try {
const response = await client.send(command);
console.log('Object ACL retrieved successfully');
console.log('Owner:', response.Owner);
console.log('Grants:', response.Grants);
} catch (err) {
console.error('Error getting object ACL:', err);
}
Obtener el estado del control de versiones
const { GetBucketVersioningCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketVersioningCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Bucket versioning configuration retrieved successfully');
console.log('Status:', response.Status);
// MFADelete is always undefined for IBM COS.
console.log('MFADelete:', response.MFADelete);
} catch (err) {
console.error('Error:', err.message);
}
Obtener una versión específica de un objeto
const { GetObjectCommand } = require('ibm-cos-sdk-v2');
const command = new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'my-file.txt',
VersionId: '<VERSION_ID>'
});
try {
const response = await client.send(command);
console.log('Version ID:', response.VersionId);
// Stream response.Body to a file or buffer as needed.
} catch (err) {
console.error('Error:', err.message);
}
Subir un objeto a un depósito con control de versiones
Cuando el control de versiones está activado, cada PutObjectCommand llamada crea una nueva versión. La respuesta incluye el nuevo VersionId.
const { PutObjectCommand } = require('ibm-cos-sdk-v2');
const command = new PutObjectCommand({
Bucket: 'my-versioned-bucket',
Key: 'my-file.txt',
Body: 'Hello, World!'
});
try {
const response = await client.send(command);
console.log('Object uploaded successfully');
console.log('Version ID:', response.VersionId);
} catch (err) {
console.error('Error:', err.message);
}
Cómo eliminar una versión específica de un objeto
Elimina de forma permanente una versión específica de un objeto incluyendo su VersionId. Si un depósito versionado no tiene un identificador de versión, se crea en su lugar un marcador de eliminación.
const { DeleteObjectCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteObjectCommand({
Bucket: 'my-versioned-bucket',
Key: 'my-file.txt',
VersionId: 'YOUR_VERSION_ID_HERE'
});
try {
const response = await client.send(command);
console.log('Object version deleted successfully');
console.log('Deleted Version ID:', response.VersionId);
console.log('Delete Marker:', response.DeleteMarker ? 'Yes' : 'No');
} catch (err) {
console.error('Error:', err.message);
}
Configuración de la protección de buckets (WORM)
IBM Cloud Object Storage Admite la protección de buckets de tipo Write-Once-Read-Many (WORM) para el cumplimiento normativo y la retención de datos.
Configuración de la protección de los buckets:
const { PutBucketProtectionConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketProtectionConfigurationCommand({
Bucket: 'my-protected-bucket',
ProtectionConfiguration: {
Status: 'Retention',
MinimumRetention: { Days: 1 },
DefaultRetention: { Days: 30 },
MaximumRetention: { Days: 365 },
},
});
try {
await client.send(command);
console.log('Bucket protection configuration set successfully');
} catch (err) {
console.error('Error configuring protection:', err.message);
}
Cómo activar la protección de buckets:
const { GetBucketProtectionConfigurationCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketProtectionConfigurationCommand({
Bucket: 'my-protected-bucket'
});
try {
const response = await client.send(command);
console.log('Bucket protection configuration retrieved successfully');
console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
console.error('Error getting protection config:', err);
}
Gestión de retenciones legales
Las retenciones legales impiden la eliminación de objetos, independientemente de que haya vencido el plazo de conservación. Cada retención se identifica mediante un identificador único y todas las retenciones deben eliminarse explícitamente antes de que se pueda borrar un objeto.
Nota: Las retenciones legales requieren que el depósito tenga configurada una protección COS ( IBM ).
Añadir una retención legal:
const { AddLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new AddLegalHoldCommand({
Bucket: 'my-protected-bucket',
Key: 'important-document.pdf',
RetentionLegalHoldId: 'legal-case-12345'
});
try {
await client.send(command);
console.log('Legal hold added');
} catch (err) {
console.error('Error adding legal hold:', err);
}
Relación de retenciones legales:
const { ListLegalHoldsCommand } = require('ibm-cos-sdk-v2');
const command = new ListLegalHoldsCommand({
Bucket: 'my-protected-bucket',
Key: 'important-document.pdf'
});
try {
const response = await client.send(command);
console.log('Legal holds listed successfully');
console.log('Legal holds:', JSON.stringify(response.LegalHolds, null, 2));
} catch (err) {
console.error('Error listing legal holds:', err);
}
Cómo eliminar una retención legal:
const { DeleteLegalHoldCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteLegalHoldCommand({
Bucket: 'my-protected-bucket',
Key: 'important-document.pdf',
RetentionLegalHoldId: 'legal-case-12345'
});
try {
await client.send(command);
console.log('Legal hold removed');
} catch (err) {
console.error('Error removing legal hold:', err);
}
Creación de un depósito cifrado de Key Protect
IBM Key Protect Ofrece gestión de claves de cifrado para el cifrado a nivel de depósito:
const { CreateBucketCommand } = require('ibm-cos-sdk-v2');
const command = new CreateBucketCommand({
Bucket: 'my-encrypted-bucket',
CreateBucketConfiguration: {
LocationConstraint: 'us-south-standard'
},
IBMSSEKPEncryptionAlgorithm: 'AES256',
IBMSSEKPCustomerRootKeyCrn: 'crn:v1:bluemix:public:kms:us-south:...'
});
try {
await client.send(command);
console.log('Encrypted bucket created');
} catch (err) {
console.error('Error creating encrypted bucket:', err);
}
Cambiar el nombre de un objeto
RenameObject es una operación atómica específica de COS ( IBM ) del lado del servidor. No se transfieren datos, solo los cambios clave:
const { RenameObjectCommand } = require('ibm-cos-sdk-v2');
const command = new RenameObjectCommand({
Bucket: 'my-bucket',
Key: 'new-object-key', // destination key
RenameSource: 'my-bucket/old-object-key' // source: bucket/key
});
try {
await client.send(command);
console.log('Object renamed successfully');
} catch (err) {
console.error('Error:', err.message);
}
Actualización del cifrado de objetos
UpdateObjectEncryption Actualiza la referencia de la clave de cifrado de un objeto existente. Requiere que el bucket tenga configurado un IBM, Key Protect o HPCS:
const { UpdateObjectEncryptionCommand } = require('ibm-cos-sdk-v2');
const command = new UpdateObjectEncryptionCommand({
Bucket: 'my-bucket',
Key: 'my-object.txt'
});
try {
await client.send(command);
console.log('Object encryption updated successfully');
} catch (err) {
console.error('Error:', err.message);
}
Gestión de la replicación de buckets
Cómo obtener la configuración de replicación:
const { GetBucketReplicationCommand } = require('ibm-cos-sdk-v2');
const command = new GetBucketReplicationCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Bucket replication configuration retrieved successfully');
console.log('Rules:', JSON.stringify(response.ReplicationConfiguration?.Rules, null, 2));
} catch (err) {
console.error('Error:', err.message);
}
Eliminación de la configuración de replicación:
const { DeleteBucketReplicationCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteBucketReplicationCommand({ Bucket: 'my-bucket' });
try {
await client.send(command);
console.log('Bucket replication configuration deleted successfully');
} catch (err) {
console.error('Error:', err.message);
}
Lista de errores de replicación:
const { ListBucketReplicationFailuresCommand } = require('ibm-cos-sdk-v2');
const command = new ListBucketReplicationFailuresCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Bucket replication failures listed successfully');
console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
console.error('Error:', err.message);
}
Reintentar las replicaciones fallidas:
const { PutBucketReplicationReattemptCommand } = require('ibm-cos-sdk-v2');
const command = new PutBucketReplicationReattemptCommand({ Bucket: 'my-bucket' });
try {
await client.send(command);
console.log('Bucket replication reattempt triggered successfully');
} catch (err) {
console.error('Error:', err.message);
}
Creación de una sesión
CreateSession crea un token de sesión temporal para un depósito de IBM Cloud Object Storage:
const { CreateSessionCommand } = require('ibm-cos-sdk-v2');
const command = new CreateSessionCommand({ Bucket: 'my-bucket' });
try {
const response = await client.send(command);
console.log('Session created successfully');
console.log('Response:', JSON.stringify(response, null, 2));
} catch (err) {
console.error('Error:', err.message);
}
A la espera de que un recurso esté listo
Los waiters consultan un recurso hasta que este alcanza el estado deseado, lo que elimina la necesidad de bucles de consulta manuales.
A la espera de que exista un bucket:
const { waitUntilBucketExists } = require('ibm-cos-sdk-v2');
try {
await waitUntilBucketExists(
{
client: client,
maxWaitTime: 120, // Maximum wait time in seconds
minDelay: 2, // Minimum delay between checks in seconds
maxDelay: 10 // Maximum delay between checks in seconds
},
{ Bucket: 'my-bucket' }
);
console.log('Bucket exists and is ready');
} catch (err) {
console.error('Bucket did not become available:', err);
}
Esperando a que exista un objeto:
const { waitUntilObjectExists } = require('ibm-cos-sdk-v2');
try {
await waitUntilObjectExists(
{
client: client,
maxWaitTime: 60,
minDelay: 1,
maxDelay: 5
},
{
Bucket: 'my-bucket',
Key: 'my-object.txt'
}
);
console.log('Object exists and is ready');
} catch (err) {
console.error('Object did not become available:', err);
}
Próximos pasos
- Consulta la documentación de referencia de la API de Node.js para obtener información detallada sobre todos los métodos y tipos disponibles
- Explora el repositorio « GitHub » para ver más ejemplos y código fuente
- Lee la guía de migración si vas a actualizar desde v1
- Consulta la documentación de « IBM Cloud Object Storage » para conocer las características específicas del servicio y las prácticas recomendadas
- Para obtener ayuda y asistencia:
- Plantea tus preguntas en Stack Overflow con las etiquetas «
ibm» yobject-storage - Crea una incidencia en GitHub
- Póngase en contacto con el servicio de asistencia de IBM Cloud
- Plantea tus preguntas en Stack Overflow con las etiquetas «