Charles L.
Charles L.

Reputation: 1970

Aws AppSync Query erring out while using a resolver

Im new to AWS AppSync however its been pretty easy to learn and understand.

Im trying to create a resolver that when the user runs getChore(id: "") it will return all the chore information. Which its successfully doing, the problem is within the chore there are two fields: createdBy & assignedTo which are linked to a user type.

type Chore {
    id: ID!
    title: String
    desc: String
    status: String
    reward: Float
    retryDeduction: Float
    required: Boolean
    createdDate: AWSDateTime
    date: AWSDateTime
    interval: String
    assignedTo: User
    createdBy: User
}

type User {
    id: ID!
    age: Int
    f_name: String
    l_name: String
    type: Int
    admin: Boolean
    family: Family
}

within aws appsync in trying to attach a resolver to assignedTo: User and createdBy: User so my query will look like:

 query getChore {
      getChore(id: "36d597c8-2c7e-4f63-93ee-38e5aa8f1d5b") {
        id
        ...
        ...
        assignedTo {
          id
          f_name
          l_name
        }
        createdBy {
          id
          f_name
          l_name
        }
      }
    }

however when i fire off this query im getting an error:

The provided key element does not match the schema (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException;

which i have researched and cant seem to find the correct soltuion.

The resolver im using is:

{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
    }
}

return:

$util.toJson($ctx.result)

Upvotes: 1

Views: 441

Answers (1)

Tinou
Tinou

Reputation: 6158

When you get the The provided key element does not match the schema error, it's because your request mapping template key doesn't match the primary key in DynamoDB. You can enable CloudWatch Logs in your Application settings to see exactly what was sent to DynamoDB.

I'm not able to know what's wrong with your template because your sample lacks some information, if you can answers the questions pertaining to your application: - Where are the users stored? Are they stored in their own DDB table separate from the chores, and is the hash key on the users table id as well? - In the chores table how do you know which user your chore is assignedTo or createdBy? Is there a user id stored on the chore DDB item? - Is the request mapping template you posted corresponding to the resolver attached to Chore.assignedTo? If yes, using $ctx.args.id will actually do a GetItem based on the chore id not the user it's assigned to.

Finally, I reproduced your application and I was able to make it work with a few changes.

Prerequisites:

  • I have a chores and a users DynamoDB table with both having id as hash key. These two tables are mapped as datasources in AppSync.
  • I have one chore in the chores tables that looks like
{
  "assignedTo": "1",
  "createdBy": "2",
  "id": "36d597c8-2c7e-4f63-93ee-38e5aa8f1d5b",
  "title": "Chore1"
}

and two users in the users table:

{
  "f_name": "Alice",
  "id": "2",
  "l_name": "Wonderland"
}

and

{
  "f_name": "John",
  "id": "1",
  "l_name": "McCain"
}
  • I used your GraphQL schema

Resolvers

Resolver on Query.getChore pointing to the chores table:

{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
    }
}

Resolver on Chore.assignedTo pointing to the users table (note the $ctx.source.assignedTo instead of $ctx.args)

{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.source.assignedTo),
    }
}

Similarly, resolver on Chore.createdBy pointing to the users table:

{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.source.createdBy),
    }
}

All resolvers response mapping template use the pass-through.

Running the query

Finally, when running your query:

query getChore {
      getChore(id: "36d597c8-2c7e-4f63-93ee-38e5aa8f1d5b") {
        id
        assignedTo {
          id
          f_name
          l_name
        }
        createdBy {
          id
          f_name
          l_name
        }
      }
    }

I get the following results:

{
  "data": {
    "getChore": {
      "id": "36d597c8-2c7e-4f63-93ee-38e5aa8f1d5b",
      "assignedTo": {
        "id": "1",
        "f_name": "John",
        "l_name": "McCain"
      },
      "createdBy": {
        "id": "2",
        "f_name": "Alice",
        "l_name": "Wonderland"
      }
    }
  }
}

Hope it helps!

Upvotes: 2

Related Questions