0

I'm using lambda code in python to update the dynamo db created by Amplify sam template graphgl

I set a subscription On Update Listener and it works as long as the changes to the data is done through the Amplify app, but when I change the data from the external lambda it doesn't trigger the event and the app doesn't update

I tried to follow this: How to send a GraphQL query to AppSync from python?

It seems like a good approach but I'm getting

{
  "data": {
    "listBillings": null
  },
  "errors": [
    {
      "path": [
        "listBillings"
      ],
      "data": null,
      "errorType": "Unauthorized",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "Not Authorized to access listBillings on type ModelBillingConnection"
    }
  ]
}

even though I assign the user with all AppSync permissions:

enter image description here

I also tried to create a custom policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "appsync:*",
            "Resource": "*"
        }
    ]
}

App code:

/* subscribe to update */
this.subscription = this.api
  .OnUpdateSumitPaymentListener()
  .subscribe((event: any) => {
    this.getTokenAndCalc();
   });

graphql:

type SumitPayment @model @searchable 
@auth(rules: [
  { allow: owner }  
  { allow: groups, groups: ["admin"] }
])
{
  id: ID!
  status: String
  OGCustomerID: String
  OGPaymentID: String
  OGPaymentType: String
  OGDocumentNumber: String
  subscriptionPrice: Float
  owner: String
  documentDownloadURL: String
}

Lambda:

dynamo = boto3.resource('dynamodb')

dbTable = dynamo.Table(tableName)

keys = {'id': id}

dbTable.update_item(
    Key=keys,
    UpdateExpression="SET #key = :val",
    ExpressionAttributeValues={
        ':val': value,
    },
    ExpressionAttributeNames={
        "#key": key
    }

I tried to follow this https://aws.amazon.com/premiumsupport/knowledge-center/appsync-notify-subscribers-real-time/

but it didn't make any sense, and also the Resolver in my case is completely different:

/**
 * These are available AWS AppSync utilities that you can use in your request and response handler.
 * For more information about the utilities that are currently implemented, see
 * https://docs.aws.amazon.com/en_us/appsync/latest/devguide/resolver-reference-overview-js.html#utility-resolvers.
 */
import {util} from '@aws-appsync/utils';

/**
 * This function is invoked before the request handler of the first AppSync function in the pipeline.
 * The resolver request handler allows you to perform some preparation logic
 * before executing the defined functions in your pipeline.
 * @param ctx - Contextual information for your resolver invocation
 */
export function request(ctx) {
    return {};
}

/**
 * Pipeline functions exhibit the following behaviors:
 * 1) Between your request and response handler, the functions of your pipeline resolver will run in sequence.
 * 2) The resolver's request handler result is made available to the first function as ctx.prev.result.
 * 3) Each function's response handler result is available to the next function as ctx.prev.result. 
 */

/**
 * This function is invoked after the response handler of the last AppSync function in the pipeline.
 * The resolver response handler allows you to perform some final evaluation logic
 * from the output of the last function to the expected GraphQL field type.
 * @param ctx - Contextual information for your resolver invocation. 
 */
export function response(ctx) {
    return ctx.prev.result;
}

I don't understand the None data source and how u should use it

I don't think it is correct to change things from the console when u work with SAM CLI because it will override the changes

And in the end of the tutorial he just show the same example from the beginning - that was already working, so I didn't understand what was the point of the tutorial.

Elia Weiss
  • 8,324
  • 13
  • 70
  • 110

1 Answers1

0

I was able to use this:

import requests

# establish a session with requests session
session = requests.Session()

# As found in AWS Appsync under Settings for your endpoint.
APPSYNC_API_ENDPOINT_URL = 'https://vxxxxxxxxxxxxxxxxxxy.appsync-api.ap-southeast-2.amazonaws.com/graphql'

# setup the query string (optional)
query = """query listItemsQuery {listItemsQuery {items {correlation_id, id, etc}}}"""

# Now we can simply post the request...
response = session.request(
    url=APPSYNC_API_ENDPOINT_URL,
    method='POST',
    headers={'x-api-key': '<APIKEYFOUNDINAPPSYNCSETTINGS>'},
    json={'query': query}
)

print(response.json()['data'])

in the schema I added:

type SumitPayment 
  @model
  @searchable
  @auth(
    rules: [
      { allow: public, provider: apiKey }
      { allow: owner }
      { allow: groups, groups: ["admin"] }
    ]

and created a key in AppSync Settings

enter image description here

Elia Weiss
  • 8,324
  • 13
  • 70
  • 110