How to get response from S3 getObject in Node.js? How to get response from S3 getObject in Node.js? node.js node.js

How to get response from S3 getObject in Node.js?


When doing a getObject() from the S3 API, per the docs the contents of your file are located in the Body property, which you can see from your sample output. You should have code that looks something like the following

const aws = require('aws-sdk');const s3 = new aws.S3(); // Pass in opts to S3 if necessaryvar getParams = {    Bucket: 'abc', // your bucket name,    Key: 'abc.txt' // path to the object you're looking for}s3.getObject(getParams, function(err, data) {    // Handle any error and exit    if (err)        return err;  // No error happened  // Convert Body from a Buffer to a String  let objectData = data.Body.toString('utf-8'); // Use the encoding necessary});

You may not need to create a new buffer from the data.Body object but if you need you can use the sample above to achieve that.

@aws-sdk/client-s3 (2021 Update)

Since I wrote this answer in 2016, Amazon has released a new JavaScript SDK, @aws-sdk/client-s3. This new version improves on the original getObject() by returning a promise always instead of opting in via .promise() being chained to getObject(). In addition to that, response.Body is no longer a Buffer but, one of Readable|ReadableStream|Blob. This changes the handling of the response.Data a bit. This should be more performant since we can stream the data returned instead of holding all of the contents in memory, with the trade-off being that it is a bit more verbose to implement.

In the below example the response.Body data will be streamed into an array and then returned as a string. This is the equivalent example of my original answer. Alternatively, the response.Body could use stream.Readable.pipe() to an HTTP Response, a File or any other type of stream.Writeable for further usage, this would be the more performant way when getting large objects.

If you wanted to use a Buffer, like the original getObject() response, this can be done by wrapping responseDataChunks in a Buffer.concat() instead of using Array#join(), this would be useful when interacting with binary data. To note, since Array#join() returns a string, each Buffer instance in responseDataChunks will have Buffer.toString() called implicitly and the default encoding of utf8 will be used.

const { GetObjectCommand, S3Client } = require('@aws-sdk/client-s3')const client = new S3Client() // Pass in opts to S3 if necessaryfunction getObject (Bucket, Key) {  return new Promise(async (resolve, reject) => {    const getObjectCommand = new GetObjectCommand({ Bucket, Key })    try {      const response = await client.send(getObjectCommand)        // Store all of data chunks returned from the response data stream       // into an array then use Array#join() to use the returned contents as a String      let responseDataChunks = []        // Attach a 'data' listener to add the chunks of data to our array      // Each chunk is a Buffer instance      response.Body.on('data', chunk => responseDataChunks.push(chunk))        // Once the stream has no more data, join the chunks into a string and return the string      response.Body.once('end', () => resolve(responseDataChunks.join('')))    } catch (err) {      // Handle the error or throw      return reject(err)    }   })}

@aws-sdk/client-s3 Documentation Links


Based on the answer by @peteb, but using Promises and Async/Await:

const AWS = require('aws-sdk');const s3 = new AWS.S3();async function getObject (bucket, objectKey) {  try {    const params = {      Bucket: bucket,      Key: objectKey     }    const data = await s3.getObject(params).promise();    return data.Body.toString('utf-8');  } catch (e) {    throw new Error(`Could not retrieve file from S3: ${e.message}`)  }}// To retrieve you need to use `await getObject()` or `getObject().then()`getObject('my-bucket', 'path/to/the/object.txt').then(...);


For someone looking for a NEST JS TYPESCRIPT version of the above:

    /**     * to fetch a signed URL of a file     * @param key key of the file to be fetched     * @param bucket name of the bucket containing the file     */    public getFileUrl(key: string, bucket?: string): Promise<string> {        var scopeBucket: string = bucket ? bucket : this.defaultBucket;        var params: any = {            Bucket: scopeBucket,            Key: key,            Expires: signatureTimeout  // const value: 30        };        return this.account.getSignedUrlPromise(getSignedUrlObject, params);    }    /**     * to get the downloadable file buffer of the file     * @param key key of the file to be fetched     * @param bucket name of the bucket containing the file     */    public async getFileBuffer(key: string, bucket?: string): Promise<Buffer> {        var scopeBucket: string = bucket ? bucket : this.defaultBucket;        var params: GetObjectRequest = {            Bucket: scopeBucket,            Key: key        };        var fileObject: GetObjectOutput = await this.account.getObject(params).promise();        return Buffer.from(fileObject.Body.toString());    }    /**     * to upload a file stream onto AWS S3     * @param stream file buffer to be uploaded     * @param key key of the file to be uploaded     * @param bucket name of the bucket      */    public async saveFile(file: Buffer, key: string, bucket?: string): Promise<any> {        var scopeBucket: string = bucket ? bucket : this.defaultBucket;        var params: any = {            Body: file,            Bucket: scopeBucket,            Key: key,            ACL: 'private'        };        var uploaded: any = await this.account.upload(params).promise();        if (uploaded && uploaded.Location && uploaded.Bucket === scopeBucket && uploaded.Key === key)            return uploaded;        else {            throw new HttpException("Error occurred while uploading a file stream", HttpStatus.BAD_REQUEST);        }    }