Upload image to S3 from AWS Lambda & serverless (NestJs)

Ahmer Patel
AWS Tip
Published in
3 min readMar 3, 2024

--

In this tutorial, we will delve into the process of seamlessly uploading images to S3 from AWS Lambda using NestJS. By leveraging the event-driven architecture of AWS Lambda and the modular, expressive nature of NestJS, we can create a streamlined and efficient workflow for handling image uploads. Whether you’re building a content-rich website, a dynamic image-processing service, or any application that requires efficient image management, this guide will equip you with the knowledge to integrate AWS Lambda, S3, and NestJS seamlessly.

I decided to write this blog when I came across this unknown bug which resulted in delay in my on going project. In this tutorial we will discuss step by step on how to upload to AWS S3 using serverless framework and NestJs.

Step 1: Create a service for S3

import { Injectable, Inject } from '@nestjs/common';
import { S3 } from 'aws-sdk';
import { Readable } from 'stream';

@Injectable()
export class S3Service {
constructor(@Inject('S3') private s3: S3) {}

async uploadPicture(
file,
userId: number,
mimeType: string,
): Promise<string> {
const params = {
Bucket: `Bucket name`,
Key: `obect key`,
Body: file.buffer,
ContentType: file.mimetype,
};

const { Location } = await this.s3.upload(params).promise();
return Location;
}
}
// s3.module.ts
import { Module } from '@nestjs/common';
import { S3 } from 'aws-sdk';

@Module({
providers: [
{
provide: 'S3',
useFactory: () => {
return new S3({
accessKeyId: `AWS KEY`,
secretAccessKey: `AWS SECRET`,
});
},
},
],
exports: ['S3'],
})
export class S3Module {}

After creating a module and service, We can now create an instance of this service and use it anywhere in our project.

Step 2:

  @Post('/upload')
@UseInterceptors(FileInterceptor('file'))
async editUserProfile(
@UploadedFile(
new ParseFilePipe({
validators: [
new MaxFileSizeValidator({ maxSize: 1000 }),
new FileTypeValidator({ fileType: '.(png|jpeg|jpg)' }),
],
fileIsRequired: false,
}),
) file,
) {
if (file) {
await this.s3Service.uploadPicture(file);
}
}

Simply pass the required parameters to the service. Additionally, you can validate incoming files with max size and the type of file. This looks pretty straight forward and this will work exactly how it is supposed to be.

However, if you deploy this as a serverless function you will see a damaged image getting uploaded. This is because lambda is not configured with accepting binary files.

Step 3: Adding binary file types to lambda api gateway.

There are two ways you can do this:

  1. If you are using serverless.yml you have to add this in under your provider
provider:
name: aws
runtime: nodejsxx.x
apiGateway:
binaryMediaTypes:
- '*/*'

This will make sure the lambda accept and parses the binary type files.

2. Through AWS API Gateway

Select your lambda/API > API Settings

Here you have to add Binary media types to “*/*”. You can also add any preferred types such a image/png, image/jpeg etc and It will accept only those types of files.

And congratulations, you are ready to upload images to S3 using AWS Lambda.

--

--