Move images to S3 (or Minio, GCS) instead of local disk. Generate signed URLs for secure, time-limited access. Stream uploads directly to S3 to save bandwidth. Delete objects when images are removed. By the end, images are safely stored in the cloud with proper access control.
← Back to Module 04 overviewGET /images/:id/url/:size returns time-limited download link (15 min expiry).DELETE /images/:id removes all objects from S3.Install: npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
Create src/storage/s3.ts:
import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
export class S3Storage {
private s3: S3Client;
private bucket: string;
constructor() {
this.s3 = new S3Client({ region: process.env.AWS_REGION || 'us-east-1' });
this.bucket = process.env.S3_BUCKET || 'images';
}
async uploadFile(key: string, buffer: Buffer, mimetype: string) {
const command = new PutObjectCommand({
Bucket: this.bucket,
Key: key,
Body: buffer,
ContentType: mimetype
});
return this.s3.send(command);
}
async deleteFile(key: string) {
const command = new DeleteObjectCommand({
Bucket: this.bucket,
Key: key
});
return this.s3.send(command);
}
async getSignedUrl(key: string, expirationSeconds = 900) {
const command = new GetObjectCommand({
Bucket: this.bucket,
Key: key
});
return getSignedUrl(this.s3, command, { expiresIn: expirationSeconds });
}
}