Lambda function isn't sending update mutation to Appsync subscription

0

I've created a python Lambda function that is triggered from DynamoDB update stream, which then sends a mutation query to a GraphQL endpoint in AppSync. I'm using a None datasource revolver for the mutation in AppSync and my Lambda function returns a 200 OK GraphQL response when testing, but my subscription in my Android app seems to be waiting forever and doesn't receive a mutation. I'm using an API Key for authentication and my role is given all the permissions for testing purposes. The subscription in AppSync doesn't have a resolver at all and I can't seem to test the queries in the console because of the None data source. I'm not sure how to solve this problem and could really use some help!

subscription from subscriptions.grapql:

subscription OnUpdateParkingData {
  onUpdateParkingData {
    ParkingLotName
    availableSpaces
    capacity
  }
}

subscription and mutation from schema.graphql:

type Subscription {
  onUpdateParkingData: ParkingData @aws_subscribe(mutations : ["updateParkingData"])
}

type Mutation {
  updateParkingData(input: UpdateParkingDataInput!): ParkingData
}

mutation from mutations.graphql:

mutation UpdateParkingData($input: UpdateParkingDataInput!) {
  updateParkingData(input: $input) {
    ParkingLotName
    availableSpaces
    capacity
  }
}

lambda function:

import json
from botocore.vendored import requests

GRAPHQL_URL = 'https://****.appsync-api.us-east-1.amazonaws.com/graphql'

GRAPHQL_API_KEY = "*****"

HEADERS = {
    "Content-Type": "application/json",
    "X-Api-Key":GRAPHQL_API_KEY
}



def lambda_handler(event, context):
    for record in event['Records']:
        if (record['eventName'] == "MODIFY"):
            parkingLotName = json.dumps(record['dynamodb']['NewImage']['ParkingLotName']['S'])
            capacity = json.dumps(record['dynamodb']['NewImage']['capacity']['S'])
            availableSpaces = json.dumps(record['dynamodb']['NewImage']['availableSpaces']['S'])
            
            res = {}
            json_string = "{{ParkingLotName: {}, availableSpaces: {}, capacity: {}}}".format(parkingLotName, availableSpaces, capacity)
            mutation_string = "mutation updateParkingData {{updateParkingData(input: {}){{ParkingLotName, availableSpaces, capacity}}}}".format(json_string)

            data = {"query": 
                mutation_string}

            try:
                res = requests.post(
                    GRAPHQL_URL,
                    headers=HEADERS,
                    data=json.dumps(data)
                )

            except Exception as e:
                print('error: ', e)
        
    return 'Successfully processed {} records.'.format(len(event['Records']))

Edited by: dflgal on Aug 27, 2019 12:55 PM

질문됨 5년 전1.8천회 조회
6개 답변
0

Looks like there is an issue with the way you are constructing the request. I made a similar schema to yours, and the HTTP request content should look like this:

{"query":"mutation updateParkingData {updateParkingData(input: {ParkingLotName: \"test\", availableSpaces: 1, capacity: 1}){name, spaces, capacity}}","variables":null,"operationName":"updateParkingData"}

When I ran your python code, it produced this:

{"query": "mutation updateParkingData {updateParkingData(input: {ParkingLotName: test, availableSpaces: 1, capacity: 1}){ParkingLotName, availableSpaces, capacity}}"}

Notice how the value for ParkingLotName is quoted in the working version, and not quoted in the second. Modifying json_string's declaration should produce a valid query:

json_string = "{{ParkingLotName: \"{}\", availableSpaces: {}, capacity: {}}}".format(parkingLotName, availableSpaces, capacity)
답변함 5년 전
0

Hello, thank you for the reply.

I changed the json_string line to "{{ParkingLotName: \"{}\", availableSpaces: \"{}\", capacity: \"{}\"}}".format(parkingLotName, availableSpaces, capacity) because availableSpaces and capacity are Strings as well, but when running the program, CloudWatch tells me that my mutations are failing with status code 400, malformed request, and shows me my Graphql query:

GraphQL Query: mutation updateParkingData {updateParkingData(input: {ParkingLotName: ""AquaLot"", availableSpaces: ""98"", capacity: ""29%""}){ParkingLotName, availableSpaces, capacity}}, Operation: null, Variables:
{}

How do I add the operation and the variables?

답변함 5년 전
0

Interesting, it looks like the library is already escaping the strings for you across the wire and so the additional quotes in our request caused the 400 error.

You can add variables and operationName like so:

data = {"query": mutation_string, "variables": variables, "operationName": "updateParkingData"}

Do you have any CloudWatch logs / RequestIds from other attempts so I can help you further?

답변함 5년 전
0

I'm just going to share an entire log, sorry if it's too much information!

990b6daf-56b7-44ec-b4e7-125fde581d90 Begin Request
990b6daf-56b7-44ec-b4e7-125fde581d90 GraphQL Query: mutation updateParkingData {updateParkingData(input: {ParkingLotName: "AquaLot", availableSpaces: "100", capacity: "28%"}){ParkingLotName, availableSpaces, capacity}}, Operation: null, Variables:
{}
990b6daf-56b7-44ec-b4e7-125fde581d90 Begin Execution - Type Name: Mutation and Field Name: updateParkingData
{
    "logType": "RequestMapping",
    "path": [
        "updateParkingData"
    ],
    "fieldName": "updateParkingData",
    "resolverArn": "arn:aws:appsync:us-east-1:386770239021:apis/***/types/Mutation/fields/updateParkingData",
    "requestId": "990b6daf-56b7-44ec-b4e7-125fde581d90",
    "context": {
        "arguments": {
            "input": {
                "ParkingLotName": "AquaLot",
                "availableSpaces": "100",
                "capacity": "28%"
            }
        },
        "stash": {},
        "outErrors": []
    },
    "fieldInError": false,
    "errors": [],
    "parentType": "Mutation",
    "graphQLAPIId": "****",
    "transformedTemplate": "\n{\n    \"version\": \"2017-02-28\",\n    \"payload\": {\n        \"body\": \"${context.arguments.body}\",\n        \"from\": \"${context.identity.username}\",\n        \"to\":  \"${context.arguments.to}\",\n        \"sentAt\": \"2019-08-29T17:42:55.526Z\"\n    }\n}"
}
{
    "logType": "ResponseMapping",
    "path": [
        "updateParkingData"
    ],
    "fieldName": "updateParkingData",
    "resolverArn": "arn:aws:appsync:us-east-1:386770239021:apis/***/types/Mutation/fields/updateParkingData",
    "requestId": "990b6daf-56b7-44ec-b4e7-125fde581d90",
    "context": {
        "arguments": {
            "input": {
                "ParkingLotName": "AquaLot",
                "availableSpaces": "100",
                "capacity": "28%"
            }
        },
        "result": {
            "body": "${context.arguments.body}",
            "from": "${context.identity.username}",
            "to": "${context.arguments.to}",
            "sentAt": "2019-08-29T17:42:55.526Z"
        },
        "stash": {},
        "outErrors": []
    },
    "fieldInError": false,
    "errors": [],
    "parentType": "Mutation",
    "graphQLAPIId": "****",
    "transformedTemplate": "{body=${context.arguments.body}, from=${context.identity.username}, to=${context.arguments.to}, sentAt=2019-08-29T17:42:55.526Z}"
}
990b6daf-56b7-44ec-b4e7-125fde581d90 End Field Execution
{
    "duration": 1879758,
    "logType": "ExecutionSummary",
    "requestId": "990b6daf-56b7-44ec-b4e7-125fde581d90",
    "startTime": "2019-08-29T17:42:55.525Z",
    "endTime": "2019-08-29T17:42:55.527Z",
    "parsing": {
        "startOffset": 55905,
        "duration": 43170
    },
    "version": 1,
    "validation": {
        "startOffset": 149788,
        "duration": 85183
    },
    "graphQLAPIId": "***"
}
990b6daf-56b7-44ec-b4e7-125fde581d90 Begin Tracing
{
    "duration": 1375547,
    "logType": "Tracing",
    "path": [
        "updateParkingData"
    ],
    "fieldName": "updateParkingData",
    "startOffset": 205055,
    "resolverArn": "arn:aws:appsync:us-east-1:386770239021:apis/***/types/Mutation/fields/updateParkingData",
    "requestId": "990b6daf-56b7-44ec-b4e7-125fde581d90",
    "parentType": "Mutation",
    "returnType": "ParkingData",
    "graphQLAPIId": "***"
}
{
    "duration": 25154,
    "logType": "Tracing",
    "path": [
        "updateParkingData",
        "ParkingLotName"
    ],
    "fieldName": "ParkingLotName",
    "startOffset": 1614683,
    "requestId": "990b6daf-56b7-44ec-b4e7-125fde581d90",
    "parentType": "ParkingData",
    "returnType": "String!",
    "graphQLAPIId": "****"
}
{
    "duration": 14051,
    "logType": "Tracing",
    "path": [
        "updateParkingData",
        "availableSpaces"
    ],
    "fieldName": "availableSpaces",
    "startOffset": 1730132,
    "requestId": "990b6daf-56b7-44ec-b4e7-125fde581d90",
    "parentType": "ParkingData",
    "returnType": "String",
    "graphQLAPIId": "***"
}
{
    "duration": 4516,
    "logType": "Tracing",
    "path": [
        "updateParkingData",
        "capacity"
    ],
    "fieldName": "capacity",
    "startOffset": 1748887,
    "requestId": "990b6daf-56b7-44ec-b4e7-125fde581d90",
    "parentType": "ParkingData",
    "returnType": "String",
    "graphQLAPIId": "***"
}
990b6daf-56b7-44ec-b4e7-125fde581d90 End Tracing
{
    "logType": "RequestSummary",
    "requestId": "990b6daf-56b7-44ec-b4e7-125fde581d90",
    "graphQLAPIId": "***",
    "statusCode": 200,
    "latency": 31000000
}
990b6daf-56b7-44ec-b4e7-125fde581d90 Request Headers: {Content-Type=[application/json; charset=UTF-8]}
990b6daf-56b7-44ec-b4e7-125fde581d90 Response Headers: {content-length=185, cloudfront-viewer-country=US, x-forwarded-proto=https, x-forwarded-port=443, x-forwarded-for=3.80.6.153, 70.132.32.136, via=1.1 3b8e0d5ce152e011bcc1dba2235e26b8.cloudfront.net (CloudFront), accept=*/*, cloudfront-is-smarttv-viewer=false, x-amzn-trace-id=Root=1-5d680e9f-391f37cccbb29ab0f0868678, cloudfront-is-desktop-viewer=true, cloudfront-is-tablet-viewer=false, x-api-key=*******, host=*****.appsync-api.us-east-1.amazonaws.com, content-type=application/graphql, cloudfront-forwarded-proto=https, x-amz-cf-id=zYbrFdWv4rLDAZwzccjk3Sy_-vzH5ZwBoTI7zUoM_PZuHRSyVxHyHQ==, accept-encoding=gzip, deflate, user-agent=python-requests/2.7.0 CPython/3.7.3 Linux/4.14.123-95.109.amzn2.x86_64, cloudfront-is-mobile-viewer=false}
990b6daf-56b7-44ec-b4e7-125fde581d90 End Request
답변함 5년 전
0

It looks like your response mapping template is referencing some different fields than what you expect on your types. Are you intending to map from, to, body, sentAt? I think you need to bind to your ${context.args.input} and return that.

답변함 5년 전
0

That did it! My mutations are showing up in my app now! Thank you so much; I've been stuck on this problem for days!

답변함 5년 전

로그인하지 않았습니다. 로그인해야 답변을 게시할 수 있습니다.

좋은 답변은 질문에 명확하게 답하고 건설적인 피드백을 제공하며 질문자의 전문적인 성장을 장려합니다.

질문 답변하기에 대한 가이드라인

관련 콘텐츠