AWS Amplify – How to build a voting system

Step 1: Add the following changes to the schema.graphql file

"""
Schema for Voting Feature
"""
type Vote @model {
  id: ID
  option: String
  optionCount: Int
}

type VoteType {
  id: ID
}

type Mutation {
  upVote(id: ID): VoteType
}

Step 2: Add Mutation.upVote.req.vtl in the resolvers folder of the Graphql API

{
    "version": "2018-05-29",
    "operation": "UpdateItem",
    "key" : {
      "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
    },
    "update": {
      "expression" : "set #optionCount = #optionCount + :updateValue",
      "expressionNames" : {
           "#optionCount" : "optionCount"
       },
       "expressionValues" : {
           ":updateValue" : { "N" : 1 }
       }
    }
}

Step 3: Add Mutation.upVote.res.vtl in the resolvers folder of the Graphql API

$util.toJson($ctx.result)

Step 4: Add CustomResources.json in the stacks folder

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "An auto-generated nested stack.",
  "Metadata": {},
  "Parameters": {
    "AppSyncApiId": {
      "Type": "String",
      "Description": "The id of the AppSync API associated with this project."
    },
    "AppSyncApiName": {
      "Type": "String",
      "Description": "The name of the AppSync API",
      "Default": "AppSyncSimpleTransform"
    },
    "env": {
      "Type": "String",
      "Description": "The environment name. e.g. Dev, Test, or Production",
      "Default": "NONE"
    },
    "S3DeploymentBucket": {
      "Type": "String",
      "Description": "The S3 bucket containing all deployment assets for the project."
    },
    "S3DeploymentRootKey": {
      "Type": "String",
      "Description": "An S3 key relative to the S3DeploymentBucket that points to the root\nof the deployment directory."
    }
  },
  "Resources": {
    "EmptyResource": {
      "Type": "Custom::EmptyResource",
      "Condition": "AlwaysFalse"
    },
    "UpvoteResolver": {
      "Type": "AWS::AppSync::Resolver",
      "Properties": {
        "ApiId": {
          "Ref": "AppSyncApiId"
        },
        "DataSourceName": "VoteTable",
        "TypeName": "Mutation",
        "FieldName": "upVote",
        "RequestMappingTemplateS3Location": {
          "Fn::Sub": [
            "s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/Mutation.upVote.req.vtl",
            {
              "S3DeploymentBucket": {
                "Ref": "S3DeploymentBucket"
              },
              "S3DeploymentRootKey": {
                "Ref": "S3DeploymentRootKey"
              }
            }
          ]
        },
        "ResponseMappingTemplateS3Location": {
          "Fn::Sub": [
            "s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/Mutation.upVote.res.vtl",
            {
              "S3DeploymentBucket": {
                "Ref": "S3DeploymentBucket"
              },
              "S3DeploymentRootKey": {
                "Ref": "S3DeploymentRootKey"
              }
            }
          ]
        }
      }
    }
  },
  "Conditions": {
    "HasEnvironmentParameter": {
      "Fn::Not": [
        {
          "Fn::Equals": [
            {
              "Ref": "env"
            },
            "NONE"
          ]
        }
      ]
    },
    "AlwaysFalse": {
      "Fn::Equals": ["true", "false"]
    }
  },
  "Outputs": {
    "EmptyOutput": {
      "Description": "An empty output. You may delete this if you have at least one resource above.",
      "Value": ""
    }
  }
}

Step 5: The following React code will make sure the count is updated by 1 every time the code is executed.

API.graphql(
    graphqlOperation(upVote, {
      id: <ID_OF_THE_RECORD_IN_DYNAMO_DB_TABLE>
    })
);

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *