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?