node.jsaws-lambdaaws-sdkaws-s3-client

AWS Lambda - Attempting to use the aws-sdk S3 package but getting "Not a function" errors


Pretty simple issue that I'm wondering what the issue is.

I have a simple lambda that I'm trying to integrate the S3 package into, to open a file. Here is the code:

import {S3Client} from '@aws-sdk/client-s3'

export const handler = async (event) => {

  const s3 = new S3Client({
    region: 'us-east-1'
  })

  const awsBucket = {
    Bucket: `integration-maps`,
    Key: 'testFile.json'
  }

  
  const json_file = s3.getObject(awsBucket, async (err, data) => {
    if (err){
        console.log(err, err.stack)
    }
  })
}

However, when I try to run this simple thing, I get the following error:

{
  "errorType": "TypeError",
  "errorMessage": "s3.getObject is not a function",
  "trace": [
    "TypeError: s3.getObject is not a function",
    "    at Runtime.handler (file:///var/task/index.mjs:17:24)",
    "    at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29)"
  ]
}

I tried looking up the documentation and attempting to use GetObjectCommand as instructed here, but same thing.

Thank you for any assistance!


Solution

  • The output of GetObjectCommand is a GetObjectCommandOutput where Body is a stream.

    Since you are getting a JSON file from S3 you can easily chunk the data from that Body.

    Make sure your Lambda has a role assigned to it with the necessary Permissions policies. For something simple like this all you really need is AmazonS3ReadOnlyAccess. I will assume your bucket has public access as anything else will require another Q&A.

    Here is a Node.js Lambda that has been tested on the AWS Node 22.x runtime:

    import {S3Client, GetObjectCommand} from '@aws-sdk/client-s3';
    
    export const handler = async () => {
       const s3Client = new S3Client({ region: 'us-east-1' });
       const params = {
          Bucket: 'integration-maps',
          Key: 'testFile.json',
       };
       const dataFromStream = async (stream) => {
          const chunks = [];
          return new Promise((resolve, reject) => {
             stream.on('data', (chunk) => chunks.push(chunk));
             stream.on('end', () => {
                try{
                   const data = Buffer.concat(chunks).toString('utf-8');
                   resolve(data);
                }catch(error) {
                   reject(new Error(`Rejected with error: ${error.message}`));
                }
             });
             stream.on('error', (error) => {
                reject(new Error(`Stream error: ${error.message}`));
             });
          });
       };
       try{
          const cmd = new GetObjectCommand(params);
          const resp = await s3Client.send(cmd);
    
          const data = await dataFromStream(resp.Body);
          console.log('File data:', data);
          return {
             statusCode: 200,
             body: JSON.stringify({ data: JSON.parse(data) })
          };
       }catch(e){
          console.log('S3 error:', e);
          return {
             statusCode: 500,
             body: JSON.stringify({ error: e.message })
          };
       }
    };