Uploading to AWS S3 via AWS SDK version 2 and version 3 from Express
There are 3 ways to interact with AWS
1.Through the AWS console
2.Through the AWS cli
3.Through the SDK
This post explains how to upload objects to an S3 bucket through the SDK from express JS. AWS SDK for javascript has two versions, version 2, and version 3.
Version 2
After setting up your express server, you will need to install the ‘aws-sdk’ package to make use of the version 2 SDK. To install this simply run ‘npm install aws-sdk’.
After installation, create a file, this file will house the configurations for the SDK.
First you bring in the AWS package in that file, then you update the credentials by calling AWS.config.update(). This function call accepts an object {region, credentials: {accessKeyId, secreteAccessKey}}
Note: Files will be sent as form data to express. Express can not process form data on its own, rather a package ‘multer’ has to be installed to enable express process form data. Then you initialize multer by creating a const upload= multer({}), this should be done in the global environment of the index file i.e Not in any route.
After this, export the configured AWS object. Create an index.js file, import the aws configuration imported above and set-up express server normally, then create a route, In this route you have to make use of a middleware provided by multer to process files. After defining the route, you call on upload.single(‘file‘). The ‘file’ passed into the single is the name of the field we are expecting the file to be in the form. So basically, the ‘file’ could be renamed to anything as long as it is the same field we are expecting the file in the form data.
In the express route callback function, you create a new const (let’s call it AwsUploadClient) and call the object constructor ConfiguredAws.S3({})
Create a new object that will have 3 entries
let uploadParams = { Key: req.file.originalname, Bucket: ‘Abucket’, Body: req.file.buffer }
Note: req.file.originalname and req.file.buffer is provided to us by the multer middleware.
Now we call the AwsUploadClient const we defined above as AwsUploadClient.upload(),
First argument passed into the upload function will be the object defined above and the second argument would be a callback function that will accept an error and response.
This is the way the callback will look like, of course you can do anything you want when you get a response or an error.
Note: Version 2 SDK does not support promises, hence you have to make use of the traditional callbacks
Version 3
For version 3 SDK, you have to also install a package by aws. In the command prompt you input ‘npm i @aws-sdk/client-s3’
After the installation process just like above, you create a file awsClient.js. Then you bring it in(as AWS3). The configuration for the V3 sdk is a bit different. Instead of configuring the AWS credentials directly you rather call the AWS.S3Client({}), this would return a new object as it is a constructor. In the object pass into the S3Client a single object that will contain; 1) A credentials object which will have accessKeyId, secretAccessKey and region
Then export s3Instance
Note: At this point you should have multer, express and a route set-up. For more on this refer above.
Also import the exported s3Instance in the index file. Just as above, create an uploadparams object that will have 3 entries:
1) Key: This is the key i.e filename that will be on that file in your object. We could use req.file.originamname, this is provided by the multer middleware.
2) Bucket: The bucket you want to upload to
3) Body: This is the buffer of the file you want to upload. In this case the file will be available on req.file.buffer
Then create what is called a command. To create this, you have to bring in the ‘PutObjectCommand()’ constroctor from the original ‘’@aws-sdk/client-s3', so we have to import ‘@aws-sdk/client-s3’ in the index file. The uploadparams is also passed into the PutObjectCommand.
Since version 3 supports promises we await a call to s3Instance.send(s3Instance imported from the awsClient file) and then pass into the function call command
At the end your route should look like this
With this set-up you can test the end point with postman, by sending a post request with form data with the expected field having the file in multer.single(‘file’).
You can watch this youtube video for a video illustration of this;