skip to Main Content

First of all, my apologies if this is very trivial but every solution I tried just gave errors.

In short I am new to the aws enviroment and choose a dynamodb to set up as database. I used a lamdba function to be able to batch write data from anywhere to the cloud.

It took some time but I got it all working, however by mistake I chose (or rather used the default) db location us-east-1. Now long story short for legal reasons the data should be in Europe. So I just copied everything, and migrated everything to eu-central-1.

And that’s when things when sideways… The code in us-east-1 is running on node.js 16 and uses "const AWS = require("aws-sdk");"

But the same statement in eu-central-1 keeps giving errors. If I run it in node.js 16 it states this:

errorType": "ReferenceError",
"errorMessage": "require is not defined in ES module scope, you can use import instead",
"stack": [
"ReferenceError: require is not defined in ES module scope, you can use import instead",
at file:///var/task/index.mjs:1:13",
at ModuleJob.run (node:internal/modules/esm/module_job:193:25)",
at async Promise.all (index 0)",
at async ESMLoader.import (node:internal/modules/esm/loader:530:24)",
at async _tryAwaitImport (file:///var/runtime/index.mjs:918:16)",
at async _tryRequire (file:///var/runtime/index.mjs:967:86)",
at async _loadUserApp (file:///var/runtime/index.mjs:991:16)",
at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1032:21)",
at async start (file:///var/runtime/index.mjs:1195:23)",
at async file:///var/runtime/index.mjs:1201:1"

And if I run it in node.js 18 (because I found out that the require statement is something added in this version)

"errorType": "ReferenceError",
"errorMessage": "require is not defined in ES module scope, you can use import instead",
"stack": [
"ReferenceError: require is not defined in ES module scope, you can use import instead",
at file:///var/task/index.mjs:1:13",
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)"`
]

I tried many different syntaxes but none have solved my problem or my knowledge of the problem. When I use the suggested import statement I get errors that the aws-sdk files are not found. But I tried to install them in the same location but that did not work. Probably is this a solution that I should persue but I can’t seem to find any clear information on how to succesfully attach the files (I tried to export the Lambda function and attach the aws-sdk in the folder but that gave the same errors) And more Importantly I want to know why this is occurring, because I definetly didn’t install aws-sdk in the us-east-1 region and there it works, plus the require statement is defined there.

So any reading, tips, suggestion is welcome. I ‘ll keep this update and add the code that you need to provide help (or settings or results of proposed changes).

Here is the working Lambda code (from the us-east-1), the code is the same as in eu-central-1 except for the table name and location.

const AWS = require("aws-sdk");

const dynamo = new AWS.DynamoDB.DocumentClient();



exports.handler = async (event, context) => {
  let body;
  let statusCode = 200;
  const headers = {
    "Content-Type": "application/json"
  };
  
  try {
    switch (event.routeKey) {
      case "DELETE /items/{id}":
        await dynamo
          .delete({
            TableName: "TestID",
            Key: {
              id: event.pathParameters.id
            }
          })
          .promise();
        body = `Deleted item ${event.pathParameters.id}`;
        break;
      case "GET /items/{id}":
        body = await dynamo
          .get({
            TableName: "TestID",
            Key: {
              id: event.pathParameters.id
            }
          })
          .promise();
        break;
      case "GET /items":
        body = await dynamo.scan({ TableName: "TestID" }).promise();
        break;
      case "PUT /items":
        let requestJSON = JSON.parse(event.body);
        if (!requestJSON[0].ModuleID || !requestJSON[0].DataID) {
          throw new Error("Missing required fields: ModuleID or DataID, greetings ");
        }
        await dynamo
          .put({
            TableName: "TestID",
            Item: {
              ModuleID: requestJSON[0].ModuleID,
              DataID: requestJSON[0].DataID,
              TimeStamp: requestJSON[0].TimeStamp,
              ValTemp: requestJSON[0].ValTemp
            }
          })
          .promise();
        body = `Put item ${requestJSON[0].DataID}`;
        break;
      case "PUT /items/batch":
        let requestJSONBatch = JSON.parse(event.body);
        let items = requestJSONBatch.map(item => {
          return {
            PutRequest: {
              Item: {
                ModuleID: item.ModuleID,
                DataID: item.DataID,
                TimeStamp: item.TimeStamp,
                T2: item.T2,
                ValTemp: item.ValTemp
              }
            }
          };
        });
        await dynamo
          .batchWrite({
            RequestItems: {
              "TestID": items
            }
          })
          .promise();
        body = `PUT items`;
        break;
      default:
        throw new Error(`Unsupported route: "${event.routeKey}"`);
    }
  } catch (err) {
    statusCode = 400;
    body = err.message;
  } finally {
    body = JSON.stringify(body);
  }

  return {
    statusCode,
    body,
    headers
  };
};

I followed the suggestion and changed the first line to:

const AWS = require("@aws-sdk/client-s3")

And ran the code in node.js 18 ; I get a similar error:

"errorType": "ReferenceError", "errorMessage": "require is not defined
in ES module scope, you can use import instead", "stack": [
"ReferenceError: require is not defined in ES module scope, you can
use import instead", " at file:///var/task/index.mjs:1:13", " at
ModuleJob.run (node:internal/modules/esm/module_job:194:25)" ]

2

Answers


  1. Chosen as BEST ANSWER

    The Solution,

    In the end the problem was simple, if you create a lambda function using the webinterface you don't need to add any (regular) dependencies such as the AWS-SDK module, because Amazon takes care of it. However this part stops as soon as you upload a .zip file even if you don't add anything but a code file.

    So I downloaded my working code from location x an uploade my code to a different location changed the API and Security accordingly but was unsuccesfull because I had no depencies.

    Therefore there was no "package.json" and I didn't understand any of the suggestions and the answer I was able to verify didn't help. In the end, use the aws cli (it takes some reading and understanding to set up). And add the aws-sdk and upload this using the aws cli.

    Details:

    AWS-SDK: https://github.com/aws/aws-sdk-js Instal in a specific directory:

    npm install aws-sdk
    

    Add .mjs code file to the directory use 7Zip to zip everything in the directory:

     Program Files7-Zip7z" a -r awslambdav2.zip
    

    Update this .zip file as the source for your existing function

    aws lambda update-function-code --function-name *insertFunctionName* --zip-file fileb://awslambdav2.zip
    

    And you're done! All fixed. In the end the webinterface should not be used to deploy Lambda functions.


  2. Node 18 now uses AWS SDK V3 and you should handle your code accordingly.

    This answer should help with your imports and enable you to establish a DynamoDB Client in SDK V3.

    Use:

    import * as AWS from "@aws-sdk/client-dynamodb";
    

    Also read here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search