Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS S3 SDK V3 for Node.js - GetObjectCommand v/s getSignedUrl

I'm building a web app in which I need to let users upload documents to their account and also read all the documents they have uploaded. In addition, I would like to allow users to be able to upload a profile photo as well. To handle file storage, I chose AWS S3.

However, I'm having a lot of trouble with the SDK (v3). Bear in mind I never used the previous version (v2). I installed 2 packages via npm, @aws-sdk/client-s3 and @aws-sdk/s3-request-presigner . I'm having trouble finding proper documentation for all the functionality I need. The docs I have come across are not exactly beginner friendly and don't go into a lot of detail explaining all the functionality. For example, in the case of GetObjectCommand, I am able to get a response but I'm unsure about how to actually tap into the Body and use the contents.

I'm also unsure about whether I should be using GetObjectCommand or getSignedUrl for my use case. For context, I'm using Express to build my server.

My questions -

  1. Is there any easier way to interact with S3 for my app rather than using the SDK? By easier I just mean properly documented.
  2. Am I looking at the wrong documentation? Are there other resources that make this simpler?
  3. What are the situations where one would use getSignedUrl over GetObjectCommand to read and then render stored files for a web app?

I will be extremely grateful for any and all help.

like image 267
raghav Avatar asked Feb 09 '21 14:02

raghav


Video Answer


1 Answers

  1. See response to question 2.
  2. https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/s3-example-creating-buckets.html - the documentation is perhaps more beginner friendly
  3. Depends on your use case. GetObjectCommand is the straightforward method, but you'll run into premission issues most likely. A presigned URL is a URL that you can provide to your users to grant temporary access to a specific S3 object.

Here's code for GetObjectCommand using getSignedUrl (I've also updated the doc.)

const {
    S3,
    CreateBucketCommand,
    PutObjectCommand,
    GetObjectCommand,
    DeleteObjectCommand,
    DeleteBucketCommand,
} = require("@aws-sdk/client-s3");
const { getSignedUrl  } = require("@aws-sdk/s3-request-presigner");
const fetch = require("node-fetch");

// Set parameters
// Create random names for the Amazon Simple Storage Service (Amazon S3) bucket and key.
const params = {
    Bucket: `test-bucket-${Math.ceil(Math.random() * 10 ** 10)}`,
    Key: `test-object-${Math.ceil(Math.random() * 10 ** 10)}`,
    Body: "BODY",
    Region: "REGION"
};

// Create an Amazon S3 client object.
const s3Client = new S3({ region: params.Region });

const run = async () => {
    // Create an Amazon S3 bucket.
    try {
        console.log(`Creating bucket ${params.Bucket}`);
        const data = await s3Client.send(
            new CreateBucketCommand({ Bucket: params.Bucket })
        );
        console.log(`Waiting for "${params.Bucket}" bucket creation...\n`);
    } catch (err) {
        console.log("Error creating bucket", err);
    }
    // Put the object in the Amazon S3 bucket.
    try {
        console.log(`Putting object "${params.Key}" in bucket`);
        const data = await s3Client.send(
            new PutObjectCommand({
                Bucket: params.Bucket,
                Key: params.Key,
                Body: params.Body,
            })
        );
    } catch (err) {
        console.log("Error putting object", err);
    }
    // Create a presigned URL.
    try {
        // Create the command.
        const command = new GetObjectCommand(params);

        // Create the presigned URL.
        const signedUrl = await getSignedUrl(s3Client, command, {
            expiresIn: 3600,
        });
        console.log(
            `\nGetting "${params.Key}" using signedUrl with body "${params.Body}" in v3`
        );
        console.log(signedUrl);
        const response = await fetch(signedUrl);
        console.log(
            `\nResponse returned by signed URL: ${await response.text()}\n`
        );
    }
    catch (err) {
        console.log("Error creating presigned URL", err);
    }
 
};
run();
like image 104
bmur Avatar answered Nov 02 '22 05:11

bmur