1

I have a lambda function that is triggered when a change occur in my dynamodb table. When I use the lambda resolver, I can only invoke a lambda function from my appsync which is not what I am trying to do.

I am trying to follow the answer provided here:

How do I subscribe directly to my AWS AppSync data source?

But I am having problems with the 3rd step.

Thanks

Following @Aaron_H answers this is my lambda function:

module.exports.triggerStream = async (event, context, callback) => {
if(event.Records[0].eventName === 'INSERT'){
return new Promise((resolve, reject) => {
    console.log(event.Records[0].eventName)
    console.log(JSON.stringify(context))
    console.log(JSON.stringify(event));


        const myData = { //this part is hardcoded for my tests
            "query": `
            mutation UpdateData($myDeviceID : String!, $myTs : String!, $myPayload: payloadInput){
                updateData(deviceID : $myDeviceID, ts : $myTs, payload : $myPayload){
                    checkup
                }
            }
            `,
            "variables": {
                "myDeviceID": "z55-temp",
                "myTs": "1549512000",
                "myPayload":{
                    "deviceId": "z55-temp",
                    "ts": 1549512000,
                    "value": 17.25
                }
            }
        };
    const data=JSON.stringify(myData)

    const options = {
        host: 'blablabla.appsync-api.us-east-1.amazonaws.com',
        path: '/graphql',
        method: 'POST',
        headers: {'Content-Type': 'application/json',
            "X-Api-Key" : "myApiKey"}           
    };      

    var req = https.request(options, (res) => {
      console.log('statusCode:', res.statusCode);
      console.log('headers:', res.headers);
      res.setEncoding('utf8');
      resolve('Success');

      res.on('data', (d) => {
        process.stdout.write(d);

      });
    });

    req.on('error', (e) => {
      console.error(e);
      reject(e.message);
    });
    // send the request
    req.write(data);
    req.end();
});
}

};

I am also using serverless framework, this is my serverless.yml config for my lambda function:

function:triggerStream:
handler: handler.triggerStream
events:
   - stream:
      type: dynamodb
      batchSize: 1
      startingPosition: LATEST
      arn: myExistingTableArn    

My problem is that I want to use Amazon Cognito User Pool for my appsync authorization. How am I suppose to use JWT tokens in my header if my request comes from Dynamodb streams? I have an IOT device that insert data in my table.

Thank you!

1 Answers1

1

In the solution outlined by Michael in the attached SO question, you are not working with any Lambda-type resolvers. Instead, you are setting up a DynamoDB stream to trigger a Lambda function (as outlined in https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html). Then, the code in that lambda function takes the data changed in DynamoDB to make a call to your AppSync endpoint. Make sure to send any necessary authentication headers along with the request from the Lambda.

+--------+     +---------------+     +----------------+
|DynamoDB| --> |Lambda Function| --> |AppSync mutation|
+--------+     +---------------+     +----+-----+-----+
                                          |     |
                                     +----+     +----+
                                     v               v
                               +----------+    +----------+
                               |AppSync   |    |AppSync   |
                               |subscriber|    |subscriber|
                               +----------+    +----------+

The specific operation you are sending to the appsync endpoint is a mutation you have added, that doesn't have a data source (NONE-type datasource), and uses a local resolver to re-broadcast whatever data was sent to that mutation to any subscribers who have make a subscription request. The key point to note is DynamoDB is triggering the Lambda, not AppSync.

Aaron_H
  • 1,623
  • 1
  • 12
  • 26
  • Thank you! I know have a lambda function which is triggered when an item is inserted in my Dynamodb table, the lambda function then calls a mutation. Everything works fine except for the authorization header. I used an api-key specified in the header, but when it comes to using an amazon cognito user pool, im quite lost. How can I retrieved the JWT if the calls comes from dynamodb stream? I have an iot device that inserts data in my table. – Alexis Garant Mar 12 '19 at 19:32
  • You can choose to either embed the JWT for the backend user into your Lambda function, or a username and password with which the Lambda can use to retreive a JWT from Cognito, which it will then add to the Authorization header in the AppSync mutation call. – Aaron_H Mar 13 '19 at 07:34
  • 1
    Thank you! I used adminInitiateAuth with ADMIN_NO_SRP_AUTH in my backend and it s working just like I want it to! – Alexis Garant Mar 14 '19 at 13:26
  • 1
    Is it possible dynamoDB stream triggers the `appsync` subscription directly? Let's suppose I have two appsync that modify the same Dynamo Table, I would like to one appsync interface emit the update to the other appsync endpoint. – Aecio Levy Jan 22 '20 at 12:08