AWS AppSync Velocity Templates Guide

Geometric Shapes / 180927 by Sasj
  • Introduction to Velocity Templates (this article)
  • Common Recipes: input validation, setting default values, formatting, shaping and aggregating data, error handling, authorisation (coming)
  • Debugging and troubleshooting (coming)
  • Adding CRUD operations for your types in DynamoDB (coming)
  • Connecting an external HTTP endpoint (coming)
  • Connecting a Lambda Function (coming)
  • Adding in-App searches with Elastic Search (coming)
  • Best Practices while authoring your own templates (coming)

What is AWS AppSync?

AWS AppSync is an enterprise level, fully managed, fullstack serverless data service based on GraphQL. AWS AppSync provides out-of-the-box integration with AWS services including computing, data sources, Lambda functions, file storage, text indexing, security and logging. There are clients available for Web, Mobile and Native (iOS and Android) providing real-time data synchronization and offline capabilities.

AppSync Resolvers

As your Application grows, you can extend your Schema by adding Resolvers.

  • Data Source. There a few options available including DynamoDB, RDB (Aurora/MySQL), HTTP, Lambda, Elastic Search or even no data source.
  • Request Template. This is where you can change the default behaviour to add authorisation or input validation.
  • Response Template. This is where you can add custom error handling or result transformations. Output will be part of the JSON response back to the client.

Velocity Templates

AWS AppSync uses Velocity, a Java-based template engine, to render its templates. The Velocity Engine is responsible to execute these templates and generate the corresponding output.

Hello World Example

Let’s write a HelloWorld example to learn a bit more about what we can do with VTL. Our first task will be creating the GraphQL Schema.

type Query {
helloWorld: String
}
AppSync Resolver (no data source)
query ExampleQuery {
helloWorld
}
#set( $var = "world" )
{
"version": "2018–05–29", ## behaviour for null and errors
"payload": "hello ${var}" ## $var in formal notation
}
  • Version. You can use 2017–02–28 or 2018–05–29 (recommended). The later allows defining custom behaviours for handling empty results and errors. More details.
  • Payload. When using no data source its content will be passed through to $context.result.

VTL directives are not rendered to the output but may render results. Eg: #set, #if, #else, #end, #foreach

Once executed, it will become the following output (step 3). Notice how all VTL including comments are gone.

{
"version": "2018–05–29",
"payload": "Hello world"
}
#return( $context.result )
{ 
"data" : {
"helloWorld": "Hello world"
}
}
Overview AppSync Resolver (no data source)

Passing data between templates

For this example we will calculate the rendering time between our templates. Let’s change our query a bit by adding an alias.

query ExampleQuery {
helloWorld
alias: helloWorld
}

Tip: save some keystrokes using $ctx instead of $context

Now, let’s change our Request Template to:

$util.qr($ctx.stash.put("t0", $util.time.nowEpochMilliSeconds()))
{
"version": "2018–05–29",
"payload": "Hello world"
}
#set( $t1 = $util.time.nowEpochMilliSeconds() )
#set( $total = $t1 - $ctx.stash.t0 )
#return( "${ctx.result} [${total} ms] [$ctx.stash.t0..${t1}]" )
{
"data": {
"helloWorld": "Hello world [7 ms] [1553389693379..1553389693386]",
"alias": "Hello world [20 ms] [1553389693382..1553389693402]"
}
{
"data": {
"a0": "Hello world [26 ms] [1553389576785..1553389576811]",
"a1": "Hello world [41 ms] [1553389576788..1553389576829]",
"a2": "Hello world [47 ms] [1553389576802..1553389576849]",
"a3": "Hello world [59 ms] [1553389576805..1553389576864]",
"a4": "Hello world [81 ms] [1553389576808..1553389576889]",
"a5": "Hello world [25 ms] [1553389576785..1553389576810]",
"a6": "Hello world [41 ms] [1553389576788..1553389576829]",
"a7": "Hello world [41 ms] [1553389576802..1553389576843]",
"a8": "Hello world [52 ms] [1553389576805..1553389576857]",
"a9": "Hello world [75 ms] [1553389576808..1553389576883]",
"a10": "Hello world [3 ms] [1553389576785..1553389576788]"
}
}
AppSync Resolver using stash (simplified)

Conclusion

Velocity Templates are fast and provide a very rich set of features. I can’t wait to share with you the next sections!

Thanks for reading

Would you like to blog about AppSync? Feel free to reach out to us to discuss what areas you would like to cover.

Looking for speakers? Look no more

Are you an organiser of a meetup, event or conference interested in talks or workshops showing how to build AWSome Apps using GraphQL, Amplify and AppSync?

Nader Dabit (#1), Kurt Kemple (#2), Dennis Hills (#3), Gerard Sans (#4)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Gerard Sans

Gerard Sans

Helping Devs to succeed #AI #web3 / ex @AWSCloud / Just be AWSome / MC Speaker Trainer Community Leader @web3_london / @ReactEurope @ReactiveConf @ngcruise