Como usar o Node.js V2

O IBM Cloud® Object Storage SDK for Node.js v2 oferece recursos para aproveitar ao máximo o IBM Cloud Object Storage.

O site IBM Cloud Object Storage SDK for Node.js v2 é abrangente, com muitos recursos e funcionalidades que vão além do escopo e do espaço deste guia. Para obter documentação detalhada sobre classes e métodos, consulte a documentação de referência da API do Node.js. O código-fonte pode ser localizado no Repositório GitHub.

Novidades em v2

O IBM Cloud Object Storage SDK for Node.js v2 é uma versão modernizada, desenvolvida com base na arquitetura do SDK AWS v3, trazendo melhorias significativas:

  • Arquitetura modular — Importe apenas os comandos e clientes de que você precisa
  • Design orientado a promessas — Suporte nativo a async/await com tratamento de erros mais simples
  • Pacotes menores — módulos que podem ser removidos pelo Tree-Shake reduzem o tamanho do aplicativo
  • JavaScript moderno — Aproveita os recursos do ES6+ e o suporte ao TypeScript
  • Pilha de middleware — Pipeline extensível de solicitação/resposta
  • Melhor tratamento de erros — Tipos de erros estruturados com informações detalhadas

Para desenvolvedores que estão migrando do v1, consulte o Guia de Migração.

Obtendo o SDK

A maneira recomendada de instalar o COS IBM SDK for Node.js é usar o gerenciador de pacotes npm para Node.js. Basta digitar o seguinte em uma janela de terminal:

npm install ibm-cos-sdk-v2

Pré-requisitos

  • Node.js 18 ou posterior — O SDK requer a versão mínima do Node.js 18 ou posterior.
  • Uma instância de IBM Cloud Object Storage
  • Uma chave de API de IBM Cloud Identity and Access Management com, no mínimo, permissões de “ Writer ”
  • O ID da instância do COS com a qual você está trabalhando
  • Endpoint de aquisição de token
  • Terminal em serviço

Esses valores podem ser encontrados no Console do IBM Cloud, gerando uma “credencial de serviço”.

Importar pacotes

Depois de instalar o SDK, você precisará importar os pacotes necessários para seus aplicativos Node.js a fim de utilizar o SDK, conforme mostrado no exemplo a seguir:

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';

Referências do SDK

Classes Principais

  • S3Client- Cliente principal para interagir com IBM Cloud Object Storage
  • Classes de comando — Cada operação possui uma classe de comando correspondente (por exemplo, PutObjectCommand, GetObjectCommand)

Configuração

  • S3Client construtor- Cria um novo cliente do S3 com opções de configuração
  • região- Define a região do cliente
  • endpoint- Define o endpoint do serviço URL
  • credenciais- Define as credenciais de autenticação

Criação de um cliente e obtenção das credenciais do serviço

Para se conectar ao IBM Cloud Object Storage, um cliente é criado e configurado fornecendo informações de credenciais (Chave de API e ID da instância de serviço). Esses valores também podem ser originados automaticamente de um arquivo de credenciais ou de variáveis de ambiente.

As credenciais podem ser localizadas criando uma Credencial de serviço ou por meio da CLI.

Utilizando a autenticação IAM d IBM

O exemplo a seguir mostra como criar um cliente usando a autenticação IAM d IBM com uma chave 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>'
  }
});

As opções de configuração necessárias são:

  • endpoint- O endpoint URL para a região do seu bucket do COS
  • region- A região onde seu bucket está localizado
  • credentials.apiKey- Sua chave de API do IBM Cloud com as permissões adequadas
  • credentials.serviceInstanceId- O CRN (Cloud Resource Name) da sua instância do COS

Exemplos de código

Os exemplos a seguir pressupõem que você já tenha criado um cliente, conforme mostrado na seção anterior.

Criando um depósito

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);
}

Listando os buckets disponíveis

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);
}

Listagem de buckets com informações detalhadas

IBM Cloud Object Storage oferece uma operação de listagem estendida que retorna informações adicionais sobre o 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);
}

Como obter a localização de um 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);
}

Excluindo um bucket

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);
}

Observação: um bucket precisa estar vazio para poder ser excluído.

Envio de um objeto para um bucket

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);
}

Baixando um objeto de um bucket

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);
}

Listando objetos em um depósito

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);
}

Copiando um 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);
}

Excluindo um 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);
}

Excluindo múltiplos 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);
}

Obter metadados do 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);
}

Usando uploads de múltiplas partes

Para objetos grandes, o upload em várias partes oferece maior taxa de transferência e a possibilidade de retomar os uploads. Cada parte deve ter, no mínimo, 5 MB (exceto a última parte).

Upload manual de vários arquivos:

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);
}

Usando o Gerenciador de upload (recomendado):

Para facilitar o envio de arquivos em várias partes, use o pacote @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);
}

Listagem de uploads em várias partes

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);
}

Listando as partes de um upload com várias partes

Lista todas as partes enviadas de um upload com várias partes em andamento. Útil para verificar o andamento ou coletar ETags antes de concluir o upload.

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 uma peça de um objeto existente

Carrega uma peça copiando-a de um objeto existente. Use isso em vez de enviar bytes brutos quando os dados de origem já estiverem no 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);
}

Definindo a configuração do ciclo de vida de um bucket

As políticas de arquivamento permitem que você transfira automaticamente objetos para classes de armazenamento de arquivo após um período de tempo especificado:

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);
}

Obter a configuração do ciclo de vida de um 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);
}

Ativação do controle de versão de 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);
}

Listando versões 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);
}

Definindo a configuração d 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);
}

Configuração da marcação 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);
}

Obtendo tags 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);
}

Restaurando um objeto arquivado

Os objetos nas classes de armazenamento de arquivo devem ser restaurados antes de poderem ser acessados:

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);
}

Observação: O IBM Cloud Object Storage suporta apenas a camada de recuperação “ Bulk ” para restaurar objetos das classes de armazenamento “Vault” e “Cold Vault”.

Definição da retenção de objetos

Modo de governança: Usuários com permissões específicas do IAM podem excluir versões de objetos durante o período de retenção.

Modo de conformidade: Nenhum usuário pode excluir versões de objetos durante o período de retenção.

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);
}

Obtendo a retenção 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);
}

Criação de um bucket com o Object Lock ( S3 )

S3 O Object Lock impede que os objetos sejam excluídos ou sobrescritos por um período de retenção definido ou por tempo indeterminado. O Object Lock deve ser ativado no momento da criação do bucket — ele não pode ser adicionado a um bucket já existente.

Modo de governança: Usuários com permissões específicas do IAM podem excluir versões de objetos durante o período de retenção.

Modo de conformidade: Nenhum usuário pode excluir versões de objetos durante o período de retenção.

Esta seção aborda o Object Lock d S3-compatible. Para obter informações sobre a proteção WORM específica do COS d IBM, consulte “Configurando a proteção de buckets(WORM) ” e “Gerenciando retenções legais ”.

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);
}

Definindo a configuração do Object Lock

Define ou atualiza a regra de retenção padrão aplicada a todos os novos objetos enviados para um bucket.

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);
}

Obtendo a configuração do 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);
}

Verificando se um bucket existe (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);
  }
}

Upload em streaming a partir de um arquivo

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);
}

Download de streaming para um arquivo

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);
}

Listar todos os objetos com paginação

O SDK do v2 oferece paginadores integrados para operações que retornam resultados truncados.

Usando um 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;
  }
}

Paginação 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;
}

Geração de URLs pré-assinadas

URLs pré-assinadas permitem o acesso temporário e não autenticado a objetos. Instale primeiro o pacote presigner:

npm install @ibm-cos/s3-request-presigner

GET pré-assinado URL (download):

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 pré-assinado URL (envio):

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);
}

Obter uma configuração d 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);
}

Exclusão da configuração d 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);
}

Exclusão de tags de objetos

const { DeleteObjectTaggingCommand } = require('ibm-cos-sdk-v2');
const command = new DeleteObjectTaggingCommand({
  Bucket: 'my-bucket',
  Key: 'my-object.txt'
});
try {
  await client.send(command);
  console.log('Object tagging deleted successfully');
} catch (err) {
  console.error('Error deleting object tags:', err);
}

Envio de um objeto com metadados 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);
}

Configuração da marcação 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);
}

Exclusão de uma configuração de ciclo de vida de um 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);
}

Configurando a ACL do 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);
}

Obtendo a ACL do 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);
}

Configurando a ACL de um 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);
}

Obtendo a ACL de um 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);
}

Obtendo o status do controle de versão

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);
}

Obter a versão de um objeto específico

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);
}

Envio de um objeto para um bucket com controle de versão

Quando o controle de versões está ativado, cada chamada ao PutObjectCommand cria uma nova versão. A resposta inclui o novo site 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);
}

Exclusão de uma versão específica de um objeto

Remove permanentemente uma versão específica de um objeto ao incluir seu VersionId. Se não houver um ID de versão em um bucket com controle de versão, é criado, em vez disso, um marcador de exclusão.

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);
}

Configuração da proteção do bucket (WORM)

IBM Cloud Object Storage oferece proteção de buckets do tipo Write-Once-Read-Many (WORM) para fins de conformidade e retenção de dados.

Configuração da proteção do balde:

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);
}

Como obter proteção para o balde:

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);
}

Criação de um bucket criptografado com o serviço “ Key Protect ”

IBM Key Protect oferece gerenciamento de chaves de criptografia para criptografia no nível do bucket:

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);
}

Renomear um objeto

RenameObject é uma operação atômica específica do COS do tipo “ IBM ” executada no lado do servidor. Nenhum dado é transferido — apenas as alterações na chave:

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);
}

Atualização da criptografia de objetos

UpdateObjectEncryption atualiza a referência à chave de criptografia em um objeto existente. Requer que o bucket tenha um IBM, Key Protect ou HPCS configurado:

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);
}

Gerenciamento da replicação de buckets

Obtendo a configuração de replicação:

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);
}

Exclusão da configuração de replicação:

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 falhas na replicação:

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);
}

Repetindo tentativas de replicação que falharam:

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);
}

Criação de uma sessão

CreateSession cria um token de sessão temporário para um bucket do 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);
}

Aguardando que um recurso fique disponível

Os waiters consultam um recurso até que ele atinja o estado desejado, eliminando a necessidade de ciclos de consulta manuais.

Esperando que um balde exista:

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);
}

Aguardando a existência de um 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óximas etapas