4
votes

DynamoDB operates best with a single table per application (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-nosql-design.html), yet AppSync by default breaks that rule by the way it auto-generates code from the GraphQL schema (that AWS recommends users allow the API to do). Therefore, to use AppSync with GraphQL while upholding DynamoDB's best practices (assuming DynamoDB is the sole data source for the GraphQL API), would this approach work?

First, create a blank DynamoDB table (TheTable in this example) and give it a partition key (partitionKey) and a sort key (sortKey).

Second, manually enforce every GraphQL type to be backed by that table (TheTable). This is where AppSync automatic code generation will go the other direction.

GraphQL schema:

type Pineapple {
    partitionKey: String!
    sortKey: String!
    name: String!
}

# create varying types as long as they all map to the same table
type MachineGun {
    partitionKey: String!
    sortKey: String!
    name: String!
}

input CreatePineappleInput {
    partitionKey: String!
    sortKey: String!
    name: String!
}

type Mutation {
    createPineapple(input: CreatePineappleInput!): Pineapple
}

Third, configure your own resolvers to handle the schema (again avoid auto-generated code):

Resolver:

{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "partitionKey": $util.dynamodb.toDynamoDBJson($ctx.args.input.partitionKey),
        "sortKey": $util.dynamodb.toDynamoDBJson($ctx.args.input.sortKey),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args.input),
}

And when we run the mutation in the AppSync console:

GraphQL operation:

mutation createPineapple($createPineappleInput: CreatePineappleInput!) {
  createPineapple(input: $createPineappleInput) {
    name
  }
}

{
  "createPineappleInput": {
    "partitionKey": "attraction123",
    "sortKey": "meta",
    "name": "Looking OK"
  }
}

We get the result we hoped for:

{
  "data": {
    "createPineapple": {
      "name": "Looking OK"
    }
  }
}

Is there a reason why this wouldn't achieve single-table efficiency using AppSync?

1
I know it is a late response - but for reference for future visitors I found the answer here: github.com/aws-amplify/amplify-cli/issues/…Herald Smit

1 Answers

0
votes

I'm not sure this statement is true

DynamoDB operates best with a single table per application

Do you mind sharing where you saw this? DynamoDB does indeed work best if the table schema is built based on the application access patterns. That does not necessarily mean you must fit everything in one table.