Working with Objects

Upload, download, and manage objects in NFYio. Single file, multipart upload, presigned URLs, metadata, versioning, batch delete, and object lock (WORM).

Objects are the fundamental unit of storage in NFYio — files, images, documents, or any binary data. Each object has a key (path-like identifier), metadata, and optional version ID when versioning is enabled.

Uploading Objects

Single File Upload

AWS CLI:

aws s3 cp ./document.pdf s3://my-bucket/documents/report.pdf \
  --endpoint-url https://storage.yourdomain.com

API (curl):

curl -X PUT "https://storage.yourdomain.com/my-bucket/documents/report.pdf" \
  -H "Authorization: AWS4-HMAC-SHA256 ..." \
  -H "Content-Type: application/pdf" \
  --data-binary @document.pdf

JavaScript (AWS SDK v3):

import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';

const client = new S3Client({
  endpoint: 'https://storage.yourdomain.com',
  region: 'us-east-1',
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  },
  forcePathStyle: true,
});

await client.send(new PutObjectCommand({
  Bucket: 'my-bucket',
  Key: 'documents/report.pdf',
  Body: fileBuffer,
  ContentType: 'application/pdf',
}));

Multipart Upload (>100MB)

For large files, multipart upload improves throughput and allows resumability. The AWS CLI uses it automatically for files over the threshold.

Manual multipart with AWS CLI:

# Initiate multipart upload
UPLOAD_ID=$(aws s3api create-multipart-upload \
  --bucket my-bucket \
  --key large-video.mp4 \
  --endpoint-url https://storage.yourdomain.com \
  --query 'UploadId' --output text)

# Upload parts (e.g., 5MB each)
aws s3api upload-part \
  --bucket my-bucket \
  --key large-video.mp4 \
  --upload-id "$UPLOAD_ID" \
  --part-number 1 \
  --body part1.bin \
  --endpoint-url https://storage.yourdomain.com

# Complete multipart upload
aws s3api complete-multipart-upload \
  --bucket my-bucket \
  --key large-video.mp4 \
  --upload-id "$UPLOAD_ID" \
  --multipart-upload '{"Parts":[{"ETag":"...","PartNumber":1}]}' \
  --endpoint-url https://storage.yourdomain.com

JavaScript (high-level upload):

import { Upload } from '@aws-sdk/lib-storage';
import { S3Client } from '@aws-sdk/client-s3';

const upload = new Upload({
  client: s3Client,
  params: {
    Bucket: 'my-bucket',
    Key: 'large-video.mp4',
    Body: fileStream,
    partSize: 10 * 1024 * 1024, // 10MB
  },
});

await upload.done();

Presigned URL Upload

Generate a temporary URL for direct browser upload without exposing credentials:

import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { PutObjectCommand } from '@aws-sdk/client-s3';

const command = new PutObjectCommand({
  Bucket: 'my-bucket',
  Key: 'uploads/user-file.pdf',
  ContentType: 'application/pdf',
});

const url = await getSignedUrl(s3Client, command, { expiresIn: 3600 });
// Send url to client; they PUT the file directly

See Presigned URLs for full details.

Downloading Objects

CLI

aws s3 cp s3://my-bucket/documents/report.pdf ./report.pdf \
  --endpoint-url https://storage.yourdomain.com

API

curl -o report.pdf "https://storage.yourdomain.com/my-bucket/documents/report.pdf" \
  -H "Authorization: AWS4-HMAC-SHA256 ..."

Presigned URL Download

const command = new GetObjectCommand({
  Bucket: 'my-bucket',
  Key: 'documents/report.pdf',
});
const url = await getSignedUrl(s3Client, command, { expiresIn: 3600 });
// Share url for direct download

Object Metadata

Set custom metadata on upload:

aws s3 cp report.pdf s3://my-bucket/documents/report.pdf \
  --metadata "author=john,project=alpha" \
  --endpoint-url https://storage.yourdomain.com

System metadata includes:

  • Content-Type — MIME type
  • Content-Length — Size in bytes
  • Last-Modified — Timestamp
  • ETag — Entity tag for caching/validation

Versioning

When bucket versioning is enabled:

  • PutObject creates a new version; previous versions remain
  • DeleteObject adds a delete marker; versions are retained
  • GetObject without version returns the latest non-deleted version
# List all versions
aws s3api list-object-versions \
  --bucket my-bucket \
  --prefix documents/ \
  --endpoint-url https://storage.yourdomain.com

# Get specific version
aws s3 cp s3://my-bucket/documents/report.pdf?versionId=VERSION_ID ./report-old.pdf \
  --endpoint-url https://storage.yourdomain.com

See Object Versioning for restore and lifecycle.

Deleting Objects

Single Delete

aws s3 rm s3://my-bucket/documents/report.pdf \
  --endpoint-url https://storage.yourdomain.com

Batch Delete

Delete multiple objects in one request:

# Create delete manifest
cat > delete-list.json << EOF
{"Objects":[{"Key":"doc1.pdf"},{"Key":"doc2.pdf"},{"Key":"doc3.pdf"}]}
EOF

aws s3api delete-objects \
  --bucket my-bucket \
  --delete file://delete-list.json \
  --endpoint-url https://storage.yourdomain.com

Or recursively:

aws s3 rm s3://my-bucket/temp/ --recursive --endpoint-url https://storage.yourdomain.com

Version-Aware Delete

With versioning, delete removes the latest version (adds delete marker). To permanently remove a version:

aws s3api delete-object \
  --bucket my-bucket \
  --key documents/report.pdf \
  --version-id VERSION_ID \
  --endpoint-url https://storage.yourdomain.com

Object Lock (WORM)

Object Lock provides Write-Once-Read-Many (WORM) protection. Once an object is locked, it cannot be overwritten or deleted until the retention period expires.

Enable Object Lock at bucket creation (cannot be disabled later):

aws s3api create-bucket \
  --bucket compliance-bucket \
  --object-lock-enabled-for-bucket \
  --endpoint-url https://storage.yourdomain.com

Set retention on upload:

aws s3 cp legal-doc.pdf s3://compliance-bucket/2026/contract.pdf \
  --retention-mode COMPLIANCE \
  --retention-retain-until-date "2027-01-01T00:00:00Z" \
  --endpoint-url https://storage.yourdomain.com

Next Steps