Page updated Nov 14, 2023

Set up a function

Set up a function

You can add a Lambda function to your project which you can use alongside a REST API or as a datasource in your GraphQL API using the @function directive.

amplify add function
1amplify add function
? Select which capability you want to add: Lambda function (serverless function) ? Provide a friendly name for your resource to be used as a label for this category in the project: lambdafunction ? Provide the AWS Lambda function name: lambdafunction ? Choose the runtime that you want to use: NodeJS ? Choose the function template that you want to use: (Use arrow keys) > Hello world function CRUD function for Amazon DynamoDB table (Integration with Amazon API Gateway and Amazon DynamoDB) Serverless express function (Integration with Amazon API Gateway)
1? Select which capability you want to add: Lambda function (serverless function)
2? Provide a friendly name for your resource to be used as a label for this category in the project: lambdafunction
3? Provide the AWS Lambda function name: lambdafunction
4? Choose the runtime that you want to use: NodeJS
5? Choose the function template that you want to use: (Use arrow keys)
6> Hello world function
7 CRUD function for Amazon DynamoDB table (Integration with Amazon API Gateway and Amazon DynamoDB)
8 Serverless express function (Integration with Amazon API Gateway)

Function templates

  • The Hello World function will create a basic hello world Lambda function
  • The CRUD function for Amazon DynamoDB table (Integration with Amazon API Gateway and Amazon DynamoDB) function will add a predefined serverless-express Lambda function template for CRUD operations to DynamoDB tables (which you can create by following the CLI prompts or use the tables which you've already configured using the amplify add storage command)
  • The Serverless express function (Integration with Amazon API Gateway) will add a predefined serverless-express Lambda function template with routing enabled for your REST API paths.

You can update the Lambda execution role policies for your function to access other resources generated and maintained by the CLI using the CLI.

$ amplify update function Please select the Lambda Function you would want to update: lambdafunction ? Which setting do you want to update? Resource access permissions ? Select the category (Press <space> to select, <a> to toggle all, <i> to invert selection) > api function storage auth ? Select the operations you want to permit on <YOUR_API_NAME> (Press <space> to select, <a> to toggle all, <i> to invert selection) > Query Mutation Subscription You can access the following resource attributes as environment variables from your Lambda function API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT API_<YOUR_API_NAME>_GRAPHQLAPIIDOUTPUT API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT
1$ amplify update function
2Please select the Lambda Function you would want to update: lambdafunction
3? Which setting do you want to update? Resource access permissions
4? Select the category (Press <space> to select, <a> to toggle all, <i> to invert selection)
5> api
6 function
7 storage
8 auth
9? Select the operations you want to permit on <YOUR_API_NAME> (Press <space> to select, <a> to toggle all, <i> to invert selection)
10> Query
11 Mutation
12 Subscription
13
14You can access the following resource attributes as environment variables from your Lambda function
15 API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT
16 API_<YOUR_API_NAME>_GRAPHQLAPIIDOUTPUT
17 API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT

Behind the scenes, the CLI automates populating of the resource identifiers for the selected resources as Lambda environment variables which you will see in your function code as well. This process additionally configures CRUD level IAM policies on the Lambda execution role to access these resources from the Lambda function. For instance, you might grant permissions to your Lambda function to read/write to a DynamoDB table in the Amplify project by using the above flow and the appropriate IAM policy would be set on that Lambda function's execution policy which is scoped to that table only.

Supported Lambda runtimes

Amplify CLI enables you to create, test and deploy Lambda functions with the following runtimes:

RuntimeDefault VersionRequirements
NodeJS14.x- Install NodeJS
Java11- Install Java 11 JDK and Gradle 5+
Go1.x- Install Go
.NET Core3.1- Install .NET Core SDK
Python3.8.x- Install python3 and pipenv
- Ensure python3 and pipenv commands are available in your PATH

In order to create and test Lambda functions locally, you need to have the runtime's requirements (table above) fulfilled. You'll be asked to Choose the runtime you would like to use: when running amplify add function.

Once a runtime is selected, you can select a function template for the runtime to help bootstrap your Lambda function.

Access existing AWS resource from Lambda Function

You can grant your Lambda function access to your existing resources. After running amplify add function, the CLI generates a custom-policies.json file under the folder amplify/backend/function/<function-name>/. The file is where you can specify the resources and actions that grant Lambda Function access to the specified AWS resources.

File Structure

[ { "Action": ["s3:CreateBucket"], "Resource": ["arn:aws:s3:::*"] } ]
1[
2 {
3 "Action": ["s3:CreateBucket"],
4 "Resource": ["arn:aws:s3:::*"]
5 }
6]

Action: Specify the actions that are required to be granted to your AWS resource. Wild characters ‘*’ is accepted.

Resource: Specify resources that the AWS resource needs access. The resource accepts multiple Arns for a service and wild card character ‘*’ is accepted.

Note: Specifying resource or action as ‘*’ is not recommended as best practice. This gives the Amplify function resource Administrative privileges which should be avoided.

If your Amplify resource requires access to multiple AWS services and resources, create another block to grant access to the additional services and resources.

[ { "Action": ["s3:CreateBucket"], "Resource": ["arn:aws:s3:::*"] }, { "Action": ["iam:GetPolicy"], "Resource": ["arn:aws:iam:::policy/*"] } ]
1[
2 {
3 "Action": ["s3:CreateBucket"],
4 "Resource": ["arn:aws:s3:::*"]
5 },
6 {
7 "Action": ["iam:GetPolicy"],
8 "Resource": ["arn:aws:iam:::policy/*"]
9 }
10]

Optionally, the Effect field can be specified to use ‘Allow’ or ‘Deny’. If not specified the field defaults to ‘Allow’

{ "Action": ["s3:CreateBucket"], "Resource": ["arn:aws:s3:::*"], "Effect": "Allow" }
1{
2 "Action": ["s3:CreateBucket"],
3 "Resource": ["arn:aws:s3:::*"],
4 "Effect": "Allow"
5}

Multi-Environment Workflow

To specify AWS ARN resources across environments, an optional \${env} parameter can be used for resources. The \${env} parameter in the AWS ARN resource will get populated with the current Amplify environment name at deployment.

"Resource": ["arn:aws:s3:::${env}my-bucket"]
1"Resource": ["arn:aws:s3:::${env}my-bucket"]

Next Step

On running amplify push commands, the IAM policies specified in the custom-policies.json file will be appended to the existing IAM policy list tied to the Lambda Function's execution role.

Schedule recurring Lambda functions

Amplify CLI allows you to schedule Lambda functions to be executed periodically (e.g every minute, hourly, daily, weekly, monthly or yearly). You can also formulate more complex schedules using AWS Cron Expressions such as: “10:15 AM on the last Friday of every month”. Review the Schedule Expression for Rules documentation for more details.

To schedule your Lambda function, answer Yes to Do you want to invoke this function on a recurring schedule? in the amplify add function flow. Once you deploy a function, it'll create a CloudWatch Rule to periodically execute the selected Lambda function.

GraphQL from Lambda

You can call an AppSync GraphQL API from a Node.js app or a Lambda function. Take a basic Todo app as an example:

type Todo @model @auth(rules: [{ allow: public }]) { name: String description: String }
1type Todo @model @auth(rules: [{ allow: public }]) {
2 name: String
3 description: String
4}

This API will have operations available for Query, Mutation, and Subscription. Let's take a look at how to perform both a query as well as a mutation from a Lambda function using Node.js.

Utilizing Lambda function template (IAM authorization)

First, create a Lambda function with amplify add function and choose the AppSync - GraphQL API request (with IAM) to get started. Be sure to grant access to your GraphQL API when prompted by the CLI to grant access to other resources in the project. Alternatively, you can create the function from scratch.

amplify add function ? Select which capability you want to add: Lambda function (serverless function) ? Provide an AWS Lambda function name: myfunction ? Choose the runtime that you want to use: NodeJS ? Choose the function template that you want to use: AppSync - GraphQL API request (with IAM) Available advanced settings: - Resource access permissions - Scheduled recurring invocation - Lambda layers configuration - Environment variables configuration - Secret values configuration ? Do you want to configure advanced settings? Yes ? Do you want to access other resources in this project from your Lambda function? Yes ? Select the categories you want this function to have access to. api ? Select the operations you want to permit on <YOUR_API_NAME> Query, Mutation, Subscription You can access the following resource attributes as environment variables from your Lambda function API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT API_<YOUR_API_NAME>_GRAPHQLAPIIDOUTPUT API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT ENV REGION
1amplify add function
2? Select which capability you want to add: Lambda function (serverless function)
3? Provide an AWS Lambda function name: myfunction
4? Choose the runtime that you want to use: NodeJS
5? Choose the function template that you want to use: AppSync - GraphQL API request (with IAM)
6
7Available advanced settings:
8- Resource access permissions
9- Scheduled recurring invocation
10- Lambda layers configuration
11- Environment variables configuration
12- Secret values configuration
13
14? Do you want to configure advanced settings? Yes
15? Do you want to access other resources in this project from your Lambda function? Yes
16? Select the categories you want this function to have access to. api
17? Select the operations you want to permit on <YOUR_API_NAME> Query, Mutation, Subscription
18
19You can access the following resource attributes as environment variables from your Lambda function
20 API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT
21 API_<YOUR_API_NAME>_GRAPHQLAPIIDOUTPUT
22 API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT
23 ENV
24 REGION

The function can only be added when the GraphQL API with IAM authorization exists.

Create from scratch

amplify add function ? Select which capability you want to add: Lambda function (serverless function) ? Provide an AWS Lambda function name: myfunction ? Choose the runtime that you want to use: NodeJS ? Choose the function template that you want to use: Hello World Available advanced settings: - Resource access permissions - Scheduled recurring invocation - Lambda layers configuration - Environment variables configuration - Secret values configuration ? Do you want to configure advanced settings? Yes ? Do you want to access other resources in this project from your Lambda function? Yes ? Select the categories you want this function to have access to. api ? Select the operations you want to permit on <YOUR_API_NAME> Query, Mutation, Subscription You can access the following resource attributes as environment variables from your Lambda function API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT API_<YOUR_API_NAME>_GRAPHQLAPIIDOUTPUT API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT ENV REGION
1amplify add function
2? Select which capability you want to add: Lambda function (serverless function)
3? Provide an AWS Lambda function name: myfunction
4? Choose the runtime that you want to use: NodeJS
5? Choose the function template that you want to use: Hello World
6
7Available advanced settings:
8- Resource access permissions
9- Scheduled recurring invocation
10- Lambda layers configuration
11- Environment variables configuration
12- Secret values configuration
13
14? Do you want to configure advanced settings? Yes
15? Do you want to access other resources in this project from your Lambda function? Yes
16? Select the categories you want this function to have access to. api
17? Select the operations you want to permit on <YOUR_API_NAME> Query, Mutation, Subscription
18
19You can access the following resource attributes as environment variables from your Lambda function
20 API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT
21 API_<YOUR_API_NAME>_GRAPHQLAPIIDOUTPUT
22 API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT
23 ENV
24 REGION

The examples on this page use node-fetch to make a HTTP request to your GraphQL API. When the Node.js v18 runtime is released for Lambda this dependency can be removed in favor of native fetch To get started, add the node-fetch module as a dependency:

CommonJS:

For functions written using CommonJS, you will need to install version 2 of node-fetch

{ "name": "myfunction", "version": "2.0.0", "description": "Lambda function generated by Amplify", "main": "index.js", "license": "Apache-2.0", + "dependencies": { + "node-fetch": "2" + }, "devDependencies": { "@types/aws-lambda": "^8.10.92" } }
1{
2 "name": "myfunction",
3 "version": "2.0.0",
4 "description": "Lambda function generated by Amplify",
5 "main": "index.js",
6 "license": "Apache-2.0",
7+ "dependencies": {
8+ "node-fetch": "2"
9+ },
10 "devDependencies": {
11 "@types/aws-lambda": "^8.10.92"
12 }
13}

ESM:

{ "name": "myfunction", + "type": "module", "version": "2.0.0", "description": "Lambda function generated by Amplify", "main": "index.js", "license": "Apache-2.0", + "dependencies": { + "node-fetch": "^3.2.3" + }, "devDependencies": { "@types/aws-lambda": "^8.10.92" } }
1{
2 "name": "myfunction",
3+ "type": "module",
4 "version": "2.0.0",
5 "description": "Lambda function generated by Amplify",
6 "main": "index.js",
7 "license": "Apache-2.0",
8+ "dependencies": {
9+ "node-fetch": "^3.2.3"
10+ },
11 "devDependencies": {
12 "@types/aws-lambda": "^8.10.92"
13 }
14}

Query

Using an API Key for authenticating your requests, you can query the GraphQL API to get a list of all Todos. To paginate over the list queries, you need to pass in a limit and nextToken on the listTodos query. See more at GraphQL pagination .

import { default as fetch, Request } from 'node-fetch'; const GRAPHQL_ENDPOINT = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT; const GRAPHQL_API_KEY = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT; const query = /* GraphQL */ ` query LIST_TODOS { listTodos { items { id name description } } } `; /** * @type {import('@types/aws-lambda').APIGatewayProxyHandler} */ export const handler = async (event) => { console.log(`EVENT: ${JSON.stringify(event)}`); /** @type {import('node-fetch').RequestInit} */ const options = { method: 'POST', headers: { 'x-api-key': GRAPHQL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ query }) }; const request = new Request(GRAPHQL_ENDPOINT, options); let statusCode = 200; let body; let response; try { response = await fetch(request); body = await response.json(); if (body.errors) statusCode = 400; } catch (error) { statusCode = 400; body = { errors: [ { status: response.status, message: error.message, stack: error.stack } ] }; } return { statusCode, body: JSON.stringify(body) }; };
1import { default as fetch, Request } from 'node-fetch';
2
3const GRAPHQL_ENDPOINT = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT;
4const GRAPHQL_API_KEY = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT;
5
6const query = /* GraphQL */ `
7 query LIST_TODOS {
8 listTodos {
9 items {
10 id
11 name
12 description
13 }
14 }
15 }
16`;
17
18/**
19 * @type {import('@types/aws-lambda').APIGatewayProxyHandler}
20 */
21export const handler = async (event) => {
22 console.log(`EVENT: ${JSON.stringify(event)}`);
23
24 /** @type {import('node-fetch').RequestInit} */
25 const options = {
26 method: 'POST',
27 headers: {
28 'x-api-key': GRAPHQL_API_KEY,
29 'Content-Type': 'application/json'
30 },
31 body: JSON.stringify({ query })
32 };
33
34 const request = new Request(GRAPHQL_ENDPOINT, options);
35
36 let statusCode = 200;
37 let body;
38 let response;
39
40 try {
41 response = await fetch(request);
42 body = await response.json();
43 if (body.errors) statusCode = 400;
44 } catch (error) {
45 statusCode = 400;
46 body = {
47 errors: [
48 {
49 status: response.status,
50 message: error.message,
51 stack: error.stack
52 }
53 ]
54 };
55 }
56
57 return {
58 statusCode,
59 body: JSON.stringify(body)
60 };
61};

Mutation

In this example you will create a mutation showing how to pass in variables as arguments to create a Todo record.

import { default as fetch, Request } from 'node-fetch'; const GRAPHQL_ENDPOINT = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT; const GRAPHQL_API_KEY = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT; const query = /* GraphQL */ ` mutation CREATE_TODO($input: CreateTodoInput!) { createTodo(input: $input) { id name createdAt } } `; /** * @type {import('@types/aws-lambda').APIGatewayProxyHandler} */ export const handler = async (event) => { console.log(`EVENT: ${JSON.stringify(event)}`); const variables = { input: { name: 'Hello, Todo!' } }; /** @type {import('node-fetch').RequestInit} */ const options = { method: 'POST', headers: { 'x-api-key': GRAPHQL_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ query, variables }) }; const request = new Request(GRAPHQL_ENDPOINT, options); let statusCode = 200; let body; let response; try { response = await fetch(request); body = await response.json(); if (body.errors) statusCode = 400; } catch (error) { statusCode = 400; body = { errors: [ { status: response.status, message: error.message, stack: error.stack } ] }; } return { statusCode, body: JSON.stringify(body) }; };
1import { default as fetch, Request } from 'node-fetch';
2
3const GRAPHQL_ENDPOINT = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT;
4const GRAPHQL_API_KEY = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT;
5
6const query = /* GraphQL */ `
7 mutation CREATE_TODO($input: CreateTodoInput!) {
8 createTodo(input: $input) {
9 id
10 name
11 createdAt
12 }
13 }
14`;
15
16/**
17 * @type {import('@types/aws-lambda').APIGatewayProxyHandler}
18 */
19export const handler = async (event) => {
20 console.log(`EVENT: ${JSON.stringify(event)}`);
21
22 const variables = {
23 input: {
24 name: 'Hello, Todo!'
25 }
26 };
27
28 /** @type {import('node-fetch').RequestInit} */
29 const options = {
30 method: 'POST',
31 headers: {
32 'x-api-key': GRAPHQL_API_KEY,
33 'Content-Type': 'application/json'
34 },
35 body: JSON.stringify({ query, variables })
36 };
37
38 const request = new Request(GRAPHQL_ENDPOINT, options);
39
40 let statusCode = 200;
41 let body;
42 let response;
43
44 try {
45 response = await fetch(request);
46 body = await response.json();
47 if (body.errors) statusCode = 400;
48 } catch (error) {
49 statusCode = 400;
50 body = {
51 errors: [
52 {
53 status: response.status,
54 message: error.message,
55 stack: error.stack
56 }
57 ]
58 };
59 }
60
61 return {
62 statusCode,
63 body: JSON.stringify(body)
64 };
65};

IAM Authorization

Let's take a look at another example schema that uses iam authorization.

type Todo @model @auth(rules: [{ allow: private, provider: iam }]) { name: String description: String }
1type Todo @model @auth(rules: [{ allow: private, provider: iam }]) {
2 name: String
3 description: String
4}

The CLI will automatically configure the Lambda execution IAM role to call the GraphQL API. Before writing your Lambda function you will first need to install the appropriate AWS SDK v3 dependencies:

{ "name": "myfunction", + "type": "module", "version": "2.0.0", "description": "Lambda function generated by Amplify", "main": "index.js", "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^2.0.1", + "@aws-sdk/credential-provider-node": "^3.76.0", + "@aws-sdk/protocol-http": "^3.58.0", + "@aws-sdk/signature-v4": "^3.58.0", + "node-fetch": "^3.2.3" + }, "devDependencies": { "@types/aws-lambda": "^8.10.92" } }
1{
2 "name": "myfunction",
3+ "type": "module",
4 "version": "2.0.0",
5 "description": "Lambda function generated by Amplify",
6 "main": "index.js",
7 "license": "Apache-2.0",
8+ "dependencies": {
9+ "@aws-crypto/sha256-js": "^2.0.1",
10+ "@aws-sdk/credential-provider-node": "^3.76.0",
11+ "@aws-sdk/protocol-http": "^3.58.0",
12+ "@aws-sdk/signature-v4": "^3.58.0",
13+ "node-fetch": "^3.2.3"
14+ },
15 "devDependencies": {
16 "@types/aws-lambda": "^8.10.92"
17 }
18}

Then, the following example will sign the request to call the GraphQL API using IAM authorization.

import crypto from '@aws-crypto/sha256-js'; import { defaultProvider } from '@aws-sdk/credential-provider-node'; import { SignatureV4 } from '@aws-sdk/signature-v4'; import { HttpRequest } from '@aws-sdk/protocol-http'; import { default as fetch, Request } from 'node-fetch'; const { Sha256 } = crypto; const GRAPHQL_ENDPOINT = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT; const AWS_REGION = process.env.AWS_REGION || 'us-east-1'; const query = /* GraphQL */ ` query LIST_TODOS { listTodos { items { id name description } } } `; /** * @type {import('@types/aws-lambda').APIGatewayProxyHandler} */ export const handler = async (event) => { console.log(`EVENT: ${JSON.stringify(event)}`); const endpoint = new URL(GRAPHQL_ENDPOINT); const signer = new SignatureV4({ credentials: defaultProvider(), region: AWS_REGION, service: 'appsync', sha256: Sha256 }); const requestToBeSigned = new HttpRequest({ method: 'POST', headers: { 'Content-Type': 'application/json', host: endpoint.host }, hostname: endpoint.host, body: JSON.stringify({ query }), path: endpoint.pathname }); const signed = await signer.sign(requestToBeSigned); const request = new Request(GRAPHQL_ENDPOINT, signed); let statusCode = 200; let body; let response; try { response = await fetch(request); body = await response.json(); if (body.errors) statusCode = 400; } catch (error) { statusCode = 500; body = { errors: [ { message: error.message } ] }; } return { statusCode, body: JSON.stringify(body) }; };
1import crypto from '@aws-crypto/sha256-js';
2import { defaultProvider } from '@aws-sdk/credential-provider-node';
3import { SignatureV4 } from '@aws-sdk/signature-v4';
4import { HttpRequest } from '@aws-sdk/protocol-http';
5import { default as fetch, Request } from 'node-fetch';
6
7const { Sha256 } = crypto;
8const GRAPHQL_ENDPOINT = process.env.API_<YOUR_API_NAME>_GRAPHQLAPIENDPOINTOUTPUT;
9const AWS_REGION = process.env.AWS_REGION || 'us-east-1';
10
11const query = /* GraphQL */ `
12 query LIST_TODOS {
13 listTodos {
14 items {
15 id
16 name
17 description
18 }
19 }
20 }
21`;
22
23/**
24 * @type {import('@types/aws-lambda').APIGatewayProxyHandler}
25 */
26export const handler = async (event) => {
27 console.log(`EVENT: ${JSON.stringify(event)}`);
28
29 const endpoint = new URL(GRAPHQL_ENDPOINT);
30
31 const signer = new SignatureV4({
32 credentials: defaultProvider(),
33 region: AWS_REGION,
34 service: 'appsync',
35 sha256: Sha256
36 });
37
38 const requestToBeSigned = new HttpRequest({
39 method: 'POST',
40 headers: {
41 'Content-Type': 'application/json',
42 host: endpoint.host
43 },
44 hostname: endpoint.host,
45 body: JSON.stringify({ query }),
46 path: endpoint.pathname
47 });
48
49 const signed = await signer.sign(requestToBeSigned);
50 const request = new Request(GRAPHQL_ENDPOINT, signed);
51
52 let statusCode = 200;
53 let body;
54 let response;
55
56 try {
57 response = await fetch(request);
58 body = await response.json();
59 if (body.errors) statusCode = 400;
60 } catch (error) {
61 statusCode = 500;
62 body = {
63 errors: [
64 {
65 message: error.message
66 }
67 ]
68 };
69 }
70
71 return {
72 statusCode,
73 body: JSON.stringify(body)
74 };
75};

CommonJS

When writing functions with CommonJS, you will need to install version 2 of node-fetch:

{ "name": "myfunction", "version": "2.0.0", "description": "Lambda function generated by Amplify", "main": "index.js", "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^2.0.1", + "@aws-sdk/credential-provider-node": "^3.76.0", + "@aws-sdk/protocol-http": "^3.58.0", + "@aws-sdk/signature-v4": "^3.58.0", + "node-fetch": "2" + }, "devDependencies": { "@types/aws-lambda": "^8.10.92" } }
1{
2 "name": "myfunction",
3 "version": "2.0.0",
4 "description": "Lambda function generated by Amplify",
5 "main": "index.js",
6 "license": "Apache-2.0",
7+ "dependencies": {
8+ "@aws-crypto/sha256-js": "^2.0.1",
9+ "@aws-sdk/credential-provider-node": "^3.76.0",
10+ "@aws-sdk/protocol-http": "^3.58.0",
11+ "@aws-sdk/signature-v4": "^3.58.0",
12+ "node-fetch": "2"
13+ },
14 "devDependencies": {
15 "@types/aws-lambda": "^8.10.92"
16 }
17}

Similar to the example above you can now write your handler. The difference here is the use of require() rather than import ... from

const { Sha256 } = require('@aws-crypto/sha256-js'); const { defaultProvider } = require('@aws-sdk/credential-provider-node'); const { SignatureV4 } = require('@aws-sdk/signature-v4'); const { HttpRequest } = require('@aws-sdk/protocol-http'); const { default: fetch, Request } = require('node-fetch'); const GRAPHQL_ENDPOINT = process.env.API_ < YOUR_API_NAME > _GRAPHQLAPIENDPOINTOUTPUT; const AWS_REGION = process.env.AWS_REGION || 'us-east-1'; const query = /* GraphQL */ ` query LIST_TODOS { listTodos { items { id name description } } } `; /** * @type {import('@types/aws-lambda').APIGatewayProxyHandler} */ exports.handler = async (event) => { console.log(`EVENT: ${JSON.stringify(event)}`); const endpoint = new URL(GRAPHQL_ENDPOINT); const signer = new SignatureV4({ credentials: defaultProvider(), region: AWS_REGION, service: 'appsync', sha256: Sha256 }); const requestToBeSigned = new HttpRequest({ method: 'POST', headers: { 'Content-Type': 'application/json', host: endpoint.host }, hostname: endpoint.host, body: JSON.stringify({ query }), path: endpoint.pathname }); const signed = await signer.sign(requestToBeSigned); const request = new Request(GRAPHQL_ENDPOINT, signed); let statusCode = 200; let body; let response; try { response = await fetch(request); body = await response.json(); if (body.errors) statusCode = 400; } catch (error) { statusCode = 500; body = { errors: [ { message: error.message } ] }; } return { statusCode, body: JSON.stringify(body) }; };
1const { Sha256 } = require('@aws-crypto/sha256-js');
2const { defaultProvider } = require('@aws-sdk/credential-provider-node');
3const { SignatureV4 } = require('@aws-sdk/signature-v4');
4const { HttpRequest } = require('@aws-sdk/protocol-http');
5const { default: fetch, Request } = require('node-fetch');
6
7const GRAPHQL_ENDPOINT =
8 process.env.API_ < YOUR_API_NAME > _GRAPHQLAPIENDPOINTOUTPUT;
9const AWS_REGION = process.env.AWS_REGION || 'us-east-1';
10
11const query = /* GraphQL */ `
12 query LIST_TODOS {
13 listTodos {
14 items {
15 id
16 name
17 description
18 }
19 }
20 }
21`;
22
23/**
24 * @type {import('@types/aws-lambda').APIGatewayProxyHandler}
25 */
26exports.handler = async (event) => {
27 console.log(`EVENT: ${JSON.stringify(event)}`);
28
29 const endpoint = new URL(GRAPHQL_ENDPOINT);
30
31 const signer = new SignatureV4({
32 credentials: defaultProvider(),
33 region: AWS_REGION,
34 service: 'appsync',
35 sha256: Sha256
36 });
37
38 const requestToBeSigned = new HttpRequest({
39 method: 'POST',
40 headers: {
41 'Content-Type': 'application/json',
42 host: endpoint.host
43 },
44 hostname: endpoint.host,
45 body: JSON.stringify({ query }),
46 path: endpoint.pathname
47 });
48
49 const signed = await signer.sign(requestToBeSigned);
50 const request = new Request(GRAPHQL_ENDPOINT, signed);
51
52 let statusCode = 200;
53 let body;
54 let response;
55
56 try {
57 response = await fetch(request);
58 body = await response.json();
59 if (body.errors) statusCode = 400;
60 } catch (error) {
61 statusCode = 500;
62 body = {
63 errors: [
64 {
65 message: error.message
66 }
67 ]
68 };
69 }
70
71 return {
72 statusCode,
73 body: JSON.stringify(body)
74 };
75};

For more information on files generated in the function resource folder, see Function Category Files.