48

Mutate AWS GraphQL using AWS Lambda

 5 years ago
source link: https://www.tuicool.com/articles/hit/7zYZjuq
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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.

q6bEruZ.png!web

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)

yymMRz3.png!web

Furthermore, use following steps to create the lambda function.

Create the Lambda Function with Policies of the Execution Role

{
    "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:  jmai6fY.png!web AppSyncId:  ma6fiyb.png!web

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;
});

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

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: http://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 .


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK