DEV Community

Cover image for Uploading to S3 using NestJs
Visakh Vijayan
Visakh Vijayan

Posted on • Edited on

20 5 1 1 2

Uploading to S3 using NestJs

Gone are those days when we used to store images on our servers. Nowadays we have dedicated image servers for that purpose like AWS S3, Cloudinary, and more. The reason it's better to store on these specialized servers is because of the inbuilt image manipulation tools they come with. They can resize, add watermarks and do much more.

Here is a simple way to upload files to AWS S3 using NestJs.

  1. You will have to create a bucket on S3 for this first. A bucket is like a folder for your stuff.
  2. You will need the aws-sdk package from npm for this.
  3. Get the ACCESS_KEY and KEY_SECRET from aws.
  4. Create a service file so that it can be injected everywhere on demand.
  5. Keep all your confidential keys in your .env file.
import { Injectable, Req, Res } from '@nestjs/common';
import * as AWS from "aws-sdk";

@Injectable()
export class S3Service
{
    AWS_S3_BUCKET = process.env.AWS_S3_BUCKET;
    s3 = new AWS.S3
    ({
        accessKeyId: process.env.AWS_S3_ACCESS_KEY,
        secretAccessKey: process.env.AWS_S3_KEY_SECRET,
    });

    async uploadFile(file)
    {
        const { originalname } = file;

        await this.s3_upload(file.buffer, this.AWS_S3_BUCKET, originalname, file.mimetype);
    }

    async s3_upload(file, bucket, name, mimetype)
    {
        const params = 
        {
            Bucket: bucket,
            Key: String(name),
            Body: file,
            ACL: "public-read",
            ContentType: mimetype,
            ContentDisposition:"inline",
            CreateBucketConfiguration: 
            {
                LocationConstraint: "ap-south-1"
            }
        };

        console.log(params);

        try
        {
            let s3Response = await this.s3.upload(params).promise();

            console.log(s3Response);
        }
        catch (e)
        {
            console.log(e);
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

A couple of points to look out for here are - ACL which makes your file readable to the public. Else AWS shows "Access Denied". ContentDisposition: "inline" and ContentType - so that your file is viewed by the browser and not downloaded.

And the response structure looks like this

{
  ETag: '"<unique-key>"',
  Location: 'https://<bucket>.s3.amazonaws.com/<filename>',
  key: '<filename>',
  Key: '<filename>',
  Bucket: '<bucket>'
}
Enter fullscreen mode Exit fullscreen mode

The location key is what you want.

Happy programming!!!

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (3)

Collapse
 
ivanavendano profile image
IVAN FRANCISCO AVENDAÑO PAREDES

Visakh, greetings from Venezuela . What about if i want or i need upload a DOCX Files and a PDF Files to Amazon S3. What must be write in Params options => For example in Content Type.

const params =
{
Bucket: bucket,
Key: String(name),
Body: file,
ACL: "public-read",
ContentType: mimetype,
ContentDisposition:"inline",
CreateBucketConfiguration:
{
LocationConstraint: "ap-south-1"
}
};

Collapse
 
ivanavendano profile image
IVAN FRANCISCO AVENDAÑO PAREDES

And Visakh, i'm working in Windows 10 and NestJs ¿ what about compile time in local PC?

Collapse
 
hamza_zahidul profile image
Hamza Zahidul Islam

Thank you so much borther, i am very thank full

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more