Skip to content
Sandny Blog
  • Home
  • Java
  • JavaScript
  • AWS
  • Embedded
  • About
aws graphql with lambda AppSync

How to mutate AWS GraphQL using AWS Lambda

  • August 26, 2018September 5, 2018
  • by Coder Kai

Recently, I had to create a AWS Lambda trigger for the AWS DynamoDB table events. The tricky part on this thing was to mutate AWS GraphQL using AWS Lambda with this DynamoDB event. The reason was I wanted all the clients which were subscribed to GraphQL to get this event with modified data.

aws graphql trigger example - mutate AWS GraphQL using AWS Lambda

The problem was how to authenticate Lambda and communicate with AppSync. My mobile application was using the AWS Cognito credentials for AWS service authentication. Therefore, with the current setup I used the AWS IAM policies to authenticate the lambda function to do mutations.

Change AppSync Auth Mode to mutate AWS GraphQL using AWS Lambda

First of all, go to the AppSync and change the auth mode to 

AWS Identity and Access Management (IAM)
AWS Identity and Access Management (IAM)

AWS AppSync Auth Mode- mutate AWS GraphQL using AWS Lambda

Furthermore, use following steps to create the lambda function.

Create IAM policy to authenticate AppSync endpoint

Go to your IAM console and create the following Policy with an appropriate name.

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"appsync:GraphQL"
],
"Resource": [
"arn:aws:appsync:**-region-**:**Identity-Pool-ARN******:apis/******AppSync-API-ID***/*"
]
}
]
}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "appsync:GraphQL" ], "Resource": [ "arn:aws:appsync:**-region-**:**Identity-Pool-ARN******:apis/******AppSync-API-ID***/*" ] } ] }
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "appsync:GraphQL"
            ],
            "Resource": [
                "arn:aws:appsync:**-region-**:**Identity-Pool-ARN******:apis/******AppSync-API-ID***/*"
            ]
        }
    ]
}

Region: Your AWS Region:
Identity Pool ARN:
   click on edit identity pool and select Show ARN

Identity Pool ARN
AppSync Id:

AppSync ID - mutate AWS GraphQL using AWS Lambda

After creating this policy, attach it to the AWS Lambda executing role. Note that you can always give 

/*
/*for your GraphQL endpoint which is the default Invocation Policy likewise.

After that, create the Lambda function which can invoke the GraphQL function. For that I used Axios library. You can use any other library option too.

const AWS = require('aws-sdk');
const axios = require('node_modules/axios/lib/axios.js');
exports.handler = async (event) => {
AWS.config.update({
region: 'us-****-*',
credentials: new AWS.Credentials({
accessKeyId: "*******",
secretAccessKey: "***********",
})
});
const result = await invokeAppSync({ user1: 'dummy1', user2: 'dummy2' });
console.log(result)
return result.data;
};
const invokeAppSync = async ({ user1, user2 }) => {
let req = new AWS.HttpRequest('https://****.appsync-api.us-****-1.amazonaws.com/graphql', 'us-****-*');
req.method = 'POST';
req.headers.host = '******.appsync-api.us-****-*.amazonaws.com';
req.headers['Content-Type'] = 'multipart/form-data';
req.body = JSON.stringify({
"query":"mutation ($input: CreateMatchInput!) { createMatch(input: $input){ matchId } }",
"variables": {
"input": {
"matchId": "dummyid",
"matchUser1": user1,
"matchUser2": user2,
"timestamp": `${Date.now()}`
}
}
});
let signer = new AWS.Signers.V4(req, 'appsync', true);
signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate());
const result = await axios({
method: 'post',
url: 'https://*******.appsync-api.us-****-*.amazonaws.com/graphql',
data: req.body,
headers: req.headers
});
return result;
});
const AWS = require('aws-sdk'); const axios = require('node_modules/axios/lib/axios.js'); exports.handler = async (event) => { AWS.config.update({ region: 'us-****-*', credentials: new AWS.Credentials({ accessKeyId: "*******", secretAccessKey: "***********", }) }); const result = await invokeAppSync({ user1: 'dummy1', user2: 'dummy2' }); console.log(result) return result.data; }; const invokeAppSync = async ({ user1, user2 }) => { let req = new AWS.HttpRequest('https://****.appsync-api.us-****-1.amazonaws.com/graphql', 'us-****-*'); req.method = 'POST'; req.headers.host = '******.appsync-api.us-****-*.amazonaws.com'; req.headers['Content-Type'] = 'multipart/form-data'; req.body = JSON.stringify({ "query":"mutation ($input: CreateMatchInput!) { createMatch(input: $input){ matchId } }", "variables": { "input": { "matchId": "dummyid", "matchUser1": user1, "matchUser2": user2, "timestamp": `${Date.now()}` } } }); let signer = new AWS.Signers.V4(req, 'appsync', true); signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate()); const result = await axios({ method: 'post', url: 'https://*******.appsync-api.us-****-*.amazonaws.com/graphql', data: req.body, headers: req.headers }); return result; });
const AWS = require('aws-sdk');
const axios = require('node_modules/axios/lib/axios.js');

exports.handler = async (event) => {  
    
    AWS.config.update({
      region: 'us-****-*',
      credentials: new AWS.Credentials({
         accessKeyId: "*******",
         secretAccessKey: "***********",
      })
    });

    const result = await invokeAppSync({ user1: 'dummy1', user2: 'dummy2' });
    
    console.log(result)

    return result.data;
};


const invokeAppSync = async ({ user1, user2 }) => {
    let req = new AWS.HttpRequest('https://****.appsync-api.us-****-1.amazonaws.com/graphql', 'us-****-*');
    req.method = 'POST';
    req.headers.host = '******.appsync-api.us-****-*.amazonaws.com';
    req.headers['Content-Type'] = 'multipart/form-data';
    req.body = JSON.stringify({
        "query":"mutation ($input: CreateMatchInput!) { createMatch(input: $input){  matchId } }",
            "variables": {
                "input": {
                    "matchId": "dummyid",
                    "matchUser1": user1,
                    "matchUser2": user2,
                    "timestamp":  `${Date.now()}`
                }
            }
    });

    let signer = new AWS.Signers.V4(req, 'appsync', true);
    signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate());

    const result = await axios({
        method: 'post',
        url: 'https://*******.appsync-api.us-****-*.amazonaws.com/graphql',
        data: req.body,
        headers: req.headers
    });

    return result;
});

For this lambda function, create an access key from IAM identity users. Most importantly, this access key is using for the API signing.

Finally, if you came to this point, the job is done. This will create a AppSync mutation for the lambda function and the apps will get the subscription data.

Troubleshooting

If you get the error

appsync:GraphQL write EPROTO 139686890170176:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s23_clnt.c:802
appsync:GraphQL write EPROTO 139686890170176:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s23_clnt.c:802
appsync:GraphQL write EPROTO 139686890170176:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s23_clnt.c:802

Remember to correctly add https  and properly add host address in request. Remove the /graphql endpoint in the url.

If you need a way to connect the AppSync with a mobile app in a tricky situation use this tutorial: https://sandny.com/2018/06/28/create-aws-graphql-message-app/

Add a comment if you need any clarification in creating an AWS GraphQL from the AWS Lambda .

 

 

 

 

 

Use AWS GraphQL for React Native Message App
Query records for a list of keys in GraphQL AppSync AWS using VTL
Coder Kai
A humble developer
aws aws app sync aws graphql aws lambda iam credentials

Related articles

Multiple refs for an array of React Elements
Using multiple refs for an…
Immutable and Mutable Values in Javascript
07. Immutable and Mutable Values…
wrapper objects in javascript
06. Wrapper objects in Javascript
globals undefined and null values in javascript
05 Global, null and undefined…
Javascript Booleans and Equality
04. Javascript Guide Booleans and…
How to add Chakra UI Animations
Chakra UI Animations
Copy files from S3 to PostgreSQL RDS
How to copy files from…
SSL Websocket using Nginx Proxy
SSL Websocket proxy with Nginx…
Change python version correctly
Python is not setting correct…
optimize React.js load time
How to optimize React.js app…
Multiple refs for an array of React Elements
How to use IntersectionObserver to…
Multiple refs for an array of React Elements
How to dismiss dropdowns when…
Javascript guide Strings
03. Javascript Guide – Strings
How to fetch data with useEffect
How to fetch data with…
add styles to stripe elements
How to add styles to…
Typescript
How to use Typescript with…
how to optimize react-native map view
How to optimize react-native map…
debounce with react hooks
Avoid multiple clicks using debounce…
Numbers inJavascript
02. Javascript Guide – Numbers
Introduction to Javascript
01. Javascript Guide – Introduction…

Categories

  • android 3
  • Apollo Client 1
  • AWS 8
    • AppSync 5
    • EC2 1
    • EKS 1
    • Route53 1
    • S3 1
  • AWS Amplify 1
  • Chakra UI 1
  • Docker 1
  • Embedded 1
  • EmberJS 1
  • FCM 1
  • Godaddy 1
  • GraphQL 3
  • ios 1
  • Jasper 1
  • Java 10
    • Java 11 1
    • Java 14 1
  • JavaEE 2
  • JavaScript 39
    • Express.js 4
    • Javascript Guide 7
    • Node.js 3
    • react-native 4
    • React.js 17
    • Typescript 1
  • Kubernetes 1
  • machine learning 1
  • Maven 2
  • OCaml 3
  • PostgreSQL 1
  • Python 2
  • react-native 4
  • ReactJS 3
  • sass 1
  • Server 6
  • spark 1
  • Terraform 2
  • Ubuntu 4
  • Uncategorized 1
  • webpack 2

Recent Comments

  • binance Sign Up on How to host GoDaddy domain with AWS EC2
  • binance on Android/iOS React-native heap limit allocation failed error
  • seo 2025 buyhacklink.com on How to create Lambda function with Terraform

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Archives

  • October 2022 3
  • September 2022 7
  • May 2022 1
  • December 2021 1
  • August 2021 1
  • July 2021 6
  • June 2021 3
  • February 2021 1
  • July 2020 1
  • December 2019 5
  • November 2019 6
  • October 2019 3
  • August 2019 1
  • March 2019 1
  • February 2019 1
  • January 2019 2
  • December 2018 1
  • September 2018 2
  • August 2018 1
  • June 2018 1
  • February 2018 1
  • November 2017 2
  • October 2017 5
  • September 2017 1
  • June 2017 1
  • May 2017 10
Sandny Blog space
Theme by Colorlib Powered by WordPress