Using S3 Bucket in NestJS to Store Files

Hi! Are you ready to take your file storage to the next level? Amazon S3 (Simple Storage Service) is an amazing cloud storage solution that makes it super easy for developers to securely store and retrieve files. In this blog, we’ll guide you through the fun process of integrating AWS S3 with your NestJS application for safe file storage. We’ll cover all the essentials like installation, configuration, file uploads, and access control, complete with some cool example code. Let’s get started!

Prerequisites

Before we start, make sure you have:

  • Node.js installed
  • NestJS project set up (npm i -g @nestjs/cli && nest new my-app​)
  • AWS Account with S3 bucket created
  • IAM user with appropriate permissions

Step 1: Install Required Dependencies

Run the following command to install AWS SDK and file management dependencies:

npm install @aws-sdk/client-s3 @nestjs/config multer multer-s3

  • @aws-sdk/client-s3​: AWS SDK for interacting with S3
  • @nestjs/config​: Manage environment variables
  • multer​: Middleware for handling file uploads
  • multer-s3​: Integrates Multer with AWS S3

Step 2: Configure AWS S3 in NestJS

2.1: Add AWS Credentials in .env

AWS_ACCESS_KEY_ID=your_access_key

AWS_SECRET_ACCESS_KEY=your_secret_key

AWS_REGION=us-east-1

AWS_BUCKET_NAME=your_bucket_name

2.2: Create s3.service.ts

Create a service to handle file uploads.

import { Injectable } from '@nestjs/common';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { ConfigService } from '@nestjs/config';
import { v4 as uuidv4 } from 'uuid';

@Injectable()
export class S3Service {
  private s3: S3Client;
  private bucket: string;

  constructor(private configService: ConfigService) {
    this.s3 = new S3Client({
      region: this.configService.get<string>('AWS_REGION'),
      credentials: {
        accessKeyId: this.configService.get<string>('AWS_ACCESS_KEY_ID'),
        secretAccessKey: this.configService.get<string>('AWS_SECRET_ACCESS_KEY'),
      },
    });
    this.bucket = this.configService.get<string>('AWS_BUCKET_NAME');
  }

  async uploadFile(file: Express.Multer.File) {
    const key = `uploads/${uuidv4()}-${file.originalname}`;
    const params = {
      Bucket: this.bucket,
      Key: key,
      Body: file.buffer,
      ContentType: file.mimetype,
      ACL: 'private', // Secure access
    };
    await this.s3.send(new PutObjectCommand(params));
    return { key, url: `https://${this.bucket}.s3.amazonaws.com/${key}` };
  }
}

Step 3: Implement File Upload Controller

Create upload.controller.ts​:

import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { S3Service } from './s3.service';

@Controller('upload')
export class UploadController {
  constructor(private readonly s3Service: S3Service) {}

  @Post()
  @UseInterceptors(FileInterceptor('file'))
  async uploadFile(@UploadedFile() file: Express.Multer.File) {
    return this.s3Service.uploadFile(file);
  }
}

Step 4: Secure File Access

To ensure secure access, restrict S3 permissions:

  • Public Access Block: Ensure your bucket is private.
  • Presigned URLs for Secure Access:

Add the following method in s3.service.ts:

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

async getSignedUrl(key: string) {
  const command = new GetObjectCommand({
    Bucket: this.bucket,
    Key: key,
  });
  return getSignedUrl(this.s3, command, { expiresIn: 3600 }); // 1 hour expiry
}

Step 5: Test the API

Upload a File

curl -X POST -F "file=@/path/to/file.jpg" http://localhost:3000/upload

Get Secure File URL

Modify upload.controller.ts​:

@Get('secure/:key')
async getSecureFile(@Param('key') key: string) {
  return this.s3Service.getSignedUrl(key);
}

Now, access your file securely with http://localhost:3000/upload/secure/{file-key}​.

Hope you find it helpful!

Using S3 Bucket in NestJS to Store Files
Ram Krishna March 4, 2025
Share this post
Sign in to leave a comment
Sending Emails in Node.js