Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create folder or key on s3 using AWS SDK for Node.js?

People also ask

How do I use AWS S3 bucket in NodeJS?

Go to “Services/Storage/S3” and then click in “Create Bucket”. Then, fill the information required in the form. The bucket name must be unique, so be creative :) Click next, next, next and you will have the bucket created.

How do I access an S3 bucket from AWS SDK?

To access Amazon Simple Storage Service, create an AWS. S3 service object. Call the listBuckets method of the Amazon S3 service object to retrieve a list of your buckets. The data parameter of the callback function has a Buckets property containing an array of maps to represent the buckets.

Does S3 create folder automatically?

S3 doesn't have a folder structure, But there is something called as keys. We can create /2013/11/xyz. xls and will be shown as folder's in the console. But the storage part of S3 will take that as the file name.


S3 is not your typical file system. It's an object store. It has buckets and objects. Buckets are used to store objects, and objects comprise data (basically a file) and metadata (information about the file). When compared to a traditional file system, it's more natural to think of an S3 bucket as a drive rather than as a folder.

You don't need to pre-create a folder structure in an S3 bucket. You can simply put an object with the key cars/ford/focus.png even if cars/ford/ does not exist.

It's valuable to understand what happens at the API level in this case:

  • the putObject call will create an object at cars/ford/focus.png but it will not create anything representing the intermediate folder structure of cars/ or cars/ford/.

  • the actual folder structure does not exist, but is implied through delimiter=/ when you call listObjects, returning folders in CommonPrefixes and files in Contents.

  • you will not be able to test for the ford sub-folder using headObject because cars/ford/ does not actually exist (it is not an object). Instead you have 2 options to see if it (logically) exists:

  1. call listObjects with prefix=cars/ford/ and find it in Contents
  2. call listObjects with prefix=cars/, delimiter=/ and find it in CommonPrefixes

It is possible to create an S3 object that represents a folder, if you really want to. The AWS S3 console does this, for example. To create myfolder in a bucket named mybucket, you can issue a putObject call with bucket=mybucket, key=myfolder/, and size 0. Note the trailing forward slash.

Here's an example of creating a folder-like object using the awscli:

aws s3api put-object --bucket mybucket --key cars/ --content-length 0

In this case:

  • the folder is actually a zero-sized object whose key ends in /. Note that if you leave off the trailing / then you will get a zero-sized object that appears to be a file rather than a folder.

  • you are now able to test for the presence of cars/ in mybucket by issuing a headObject call with bucket=mybucket and key=cars/.

Finally, note that your folder delimiter can be anything you like, for example +, because it is simply part of the key and is not actually a folder separator (there are no folders). You can vary your folder delimiter from listObjects call to call if you like.


The code from @user2837831 doesn't seem to work anymore, probably with the new version of javascript sdk. So I am adding here the version of code that I am using to create a folder inside a bucket using node.js. This works with the 2.1.31 sdk. What is important is the '/' at the end of the Key value in params - using that it thinks you are trying to create a folder and not a file.

var AWS = require('aws-sdk');
AWS.config.region = 'us-east-1';
var s3Client = new AWS.S3();

var params = { Bucket: 'your_bucket_goes_here', Key: 'folderInBucket/', ACL: 'public-read', Body:'body does not matter' };

s3Client.upload(params, function (err, data) {
if (err) {
    console.log("Error creating the folder: ", err);
    } else {
    console.log("Successfully created a folder on S3");

    }
});

I find that we do not need an explicit directory creation call anymore.

Just the following works for me and automatically creates a directory hierarchy as I need.

var userFolder = 'your_bucket_name' + '/' + variable-with-dir-1-name + '/' + variable-with-dir-2-name;
// IMPORTANT : No trailing '/' at the end of the last directory name

AWS.config.region = 'us-east-1';

AWS.config.update({
    accessKeyId: 'YOUR_KEY_HERE',
    secretAccessKey: 'your_secret_access_key_here'
});

var bucket = new AWS.S3({
    params: {
        Bucket: userFolder
    }
});

var contentToPost = {
    Key: <<your_filename_here>>, 
    Body: <<your_file_here>>,
    ContentEncoding: 'base64',
    ContentType: <<your_file_content_type>>,
    ServerSideEncryption: 'AES256'
};

bucket.putObject(contentToPost, function (error, data) {

    if (error) {
        console.log("Error in posting Content [" + error + "]");
        return false;
    } /* end if error */
    else {
        console.log("Successfully posted Content");
    } /* end else error */
})
.on('httpUploadProgress',function (progress) {
    // Log Progress Information
    console.log(Math.round(progress.loaded / progress.total * 100) + '% done');
});

This is really straightforward you can do it by using the following, just remember the trailing slash.

var AWS = require("aws-sdk");
var s3 = new AWS.S3();

var params = { 
  Bucket: "mybucket", 
  Key: "mykey/"
};

s3.putObject(params).promise();