DEV Community

Cover image for How: Auto-Populated Schema Fields in AWS Amplify
Michael Liendo
Michael Liendo

Posted on

How: Auto-Populated Schema Fields in AWS Amplify

Unsplash photo by Luke Richardson


Not too long ago, I was building a schema using AWS Amplify.

Simplified a bit, it looked like this:

type Game @model {
  id: ID!
  gameName: String!
  player1: String!
  player2: String!
  currentPlayer: String!
  board: AWSJSON!
}
Enter fullscreen mode Exit fullscreen mode

Context

🗒️ For context on this scenario: Amplify is using AppSync under the hood -- A managed GraphQL API.

Furthermore, here's a breakdown of the field values:

Value Description
ID! A string that is implied to be unique. Required.
String! Any sequence of string characters. Required.
AWSJSON! Any value that is able to be stringified as JSON. This will automatically do the stringifying. Required.

The last piece to talk about is the @model directive.

By just adding that directive to our schema, Amplify will create mappings for common CRUD operations. The mapping will be between AppSync and DynamoDB.

In short, we'll have a way to create, read, update, and delete a game from our frontend, and have that data available in a database.

Learn and Be Curious

When I push this model up to AWS using the Amplify CLI:

amplify push
Enter fullscreen mode Exit fullscreen mode

Amplify will generate files so that I can perform those CRUD operations from my frontend. So to create a game, I would call the necessary methods, passing in the query, and the required fields:

const board = [[], [], []]
API.graphql(
  {
    query: createGame, 
    variables: 
    {
      input: {
        player1: "Michael",
        player2: "Jessica", 
        currentPlayer: "Michael", 
        board: board
      }
    }
)
Enter fullscreen mode Exit fullscreen mode

🗒️ Note that we didn't provide an id -- a required field.

The method above will return a JavaScript Promise. Assuming the call to create a game is successful, we will be able to dive into the response and see the following object returned:

{
  __typename: "Game",
  id: "s0m3-long-s3qnenc3",
  createdAt: 24324322 // an ISO Date
  updatedAt: 24324322,
  player1: "Michael",
  player2: "Jessica", 
  currentPlayer: "Michael",
  board: "[[], [], []]"
}
Enter fullscreen mode Exit fullscreen mode

Where did the extra fields come from?

Well, looking at the AppSync documentation for scalar types, you'll find this snippet:

$util.dynamodb.toDynamoDBJson($util.autoId()

Recall that there is a mapping between AppSync and DynamoDB. The image above is a request mapping. Written in VTL or Velocity Template Language.

In short, it's a way to specify data that goes from AppSync to DynamoDB. In this case, it's creating a unique value and adding it to the id field.

"So if Amplify is doing this part for us, then where can we find it?"

Great question, glad you asked!

Request VTL

Amplify provides all of the mapping templates in the resolvers directory. Taking a peek inside of the, we see the following:

VTL syntax

Here are the main points worth mentioning:

  • Line 2: If an id value is null, create a value
  • Line 3: Create a value for createdAt. Apply it to line 5
  • Line 10: Create the __typename and set it to Game

Conclusion

Understanding the moving parts can be tricky at first, however pulling back the curtains to reveal the magic is greatly beneficial.

Specifically, you've not only learned how certain fields are created automatically but also how you can tweak a VTL template so that your own fields are automatically added as well!

Discussion (0)