Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to autogenerate global ID using AppSync + DynamoDB

How do I generate ID automatically when I use AppSync and DynamoDB as the database source?

I have a type looking like below

type Post {
    id: ID!
    creator: String!
    createdAt: String!
    like: Int!
    dislike: Int!
    frozen: Boolean!
}

and input looking like below

input CreatePostInput {
    id: ID!
    creator: String!
    createdAt: String!
    like: Int!
    dislike: Int!
    frozen: Boolean!
}

and my mutation is obviously the combination of the two

createPost(input: CreatePostInput!): Post

However, when I make inserts I have to do something like below

mutation createPost{
  createPost(input:{
    id:2
    creator:"some creator"
    createdAt:"some date"
    like:0
    dislike:0
    frozen:false
  }){
    id
    creator
    createdAt
    like
    dislike
    frozen
  }
}

There is no way I can insert a post without having to know what the id is up to right now. Is there a way I can provide null or any random id and DynamoDB or AppSync automatically create the next index before inserting into the table?

Error generated when I update the input CreatePostInput to not accept any ID

{
  "data": {
    "createPost": null
  },
  "errors": [
    {
      "path": [
        "createPost"
      ],
      "data": null,
      "errorType": "DynamoDB:AmazonDynamoDBException",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "One or more parameter values were invalid: Type mismatch for key id expected: S actual: NULL (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 629QEM7MH9BRAJ9MHU3FM1S0U3VV4KQNSO5AEMVJF66Q9ASUAAJG)"
    }
  ]
}

My Resolver Template

{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        ## If object "id" should come from GraphQL arguments, change to $util.dynamodb.toDynamoDBJson($ctx.args.id)
        "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
like image 712
forJ Avatar asked Jul 12 '18 07:07

forJ


People also ask

What is AppSync resolver?

Data sources and resolvers are how AWS AppSync translates GraphQL requests and fetches information from your AWS resources. AWS AppSync has support for automatic provisioning and connections with certain data source types.

What is AWS AppSync?

AWS AppSync allows your applications to access exactly the data they need. Create a flexible API to securely access, manipulate, and combine data from multiple sources. Pay only for requests to your API and for real-time messages delivered to connected clients.


1 Answers

First, update the createPost resolver as:

{
  "version": "2017-02-28",
  "operation": "PutItem",
  "key": {
    "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
  },
  "attributeValues": $util.dynamodb.toMapValuesJson($ctx.args.input),
  "condition": {
    "expression": "attribute_not_exists(#id)",
    "expressionNames": {
      "#id": "id",
    },
  },
}

Then, remove the id field from your CreatePostInput input type:

input CreatePostInput {
  creator: String!
  createdAt: String!
  like: Int!
  dislike: Int!
  frozen: Boolean!
}

Save both the changes and you should be done.

If you're the one of seeing-is-believing guys like me, take a look at this egghead.io video.

like image 152
vahdet Avatar answered Nov 04 '22 23:11

vahdet