DEV Community

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

Posted on • Updated on

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!!!

Discussion (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