In my NextJS v14 project I would like to create a Dynamo db record every time a user signs up. So, I followed this official AWS tutorial, but I stumbled upon few hiccups, like:
-
When I run
amplify update function
in order to allow theMutation
operation to my function, at the end, I only get:You can access the following resource attributes as environment variables from your Lambda function: API_<MY_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT API_<MY_API_NAME>_GRAPHQLAPIIDOUTPUT
Meanwhile I would expect to also get
API_<MY_API_NAME>_GRAPHQLAPIKEYOUTPUT
to use it later in my lambda function (like shown in the guide) -
Now, here’s my
custom.js
file:const GRAPHQL_ENDPOINT = process.env.API_<MY_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT; const GRAPHQL_API_KEY = process.env.API_<MY_API_NAME>_GRAPHQLAPIIDOUTPUT; const query = /* GraphQL */ ` mutation CREATE_USER($input: CreateUserInput!) { createUser(input: $input) { username email mobilePhoneNumber } } `; /** * @type {import('@types/aws-lambda').APIGatewayProxyHandler} */ export const handler = async (event, context) => { const variables = { input: { username: event.userName, email: event.request.userAttributes.email, mobilePhoneNumber: event.request.userAttributes.phone_number, }, }; const options = { method: "POST", headers: { "x-api-key": GRAPHQL_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ query, variables }), }; const response = {}; try { const res = await fetch(GRAPHQL_ENDPOINT, options); response.data = await res.json(); if (response.data.errors) response.statusCode = 400; } catch (error) { response.statusCode = 400; response.body = { errors: [ { message: error.message, stack: error.stack, }, ], }; } return { ...response, body: JSON.stringify(response.body), }; };
The only difference from the tutorial is that I’m not using the
node-fetch
module, but rather the native fetch function since I’m using Node v18 (like suggested in this official AWS Amplify documentation and confirmed by the line"Runtime": "nodejs18.x"
inside the/amplify/backend/function/<my_function_name>/...-cloudformation-template.json
)But when this lambda function gets called, I get this error:
{ "errorType": "ReferenceError", "errorMessage": "require is not defined in ES module scope, you can use import insteadnThis file is being treated as an ES module because it has a '.js' file extension and '/var/task/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension." }
Now, as you saw, I’m not using any
require
import, but I discovered that the auto-generatedindex.js
file (inside:/amplify/backend/function/<my_function_name>/src/index.js
) has this line:/** * The array of imported modules. */ const modules = moduleNames.map((name) => require(`./${name}`));
And I’m not quite sure – also because I’m kinda new to AWS – if I’m allowed to manually edit this file in order to make it ESM compatible or not.
Just for completeness, here’s my package.json
of the lambda function:
{
"name": "...",
"type": "module",
"version": "2.0.0",
"description": "Lambda function generated by Amplify",
"main": "index.js",
"license": "Apache-2.0",
"devDependencies": {
"@types/aws-lambda": "^8.10.92"
}
}
2
Answers
Just to collect all the info on how to resolve these problems in case someone else is facing the same issues.
To resolve the first problem, i.e. not able to generate the
API_<MY_API_NAME>_GRAPHQLAPIKEYOUTPUT
, you just need to have the API key enabled as auth mode on the GraophQL API, basically runamplify update api
and picked these options:Then re-run
amplify update function
and you will have also theGRAPHQLAPIKEYOUTPUT
For the second problem, as suggested here, I've change the lambda function to use CommonJS by simply removing the
"type": "module"
(inside thepackage.json
file). On top of that I've also updated the function as such:Just to clarify, the first comment - i.e.
/* global fetch */
- is needed in order to not get this fetch error:fetch is not defined, please fix or add global fetch
In your
package.json
change"type": "module",
to"type": "commonjs",