AWS Appsync Custom Resolvers


In my current project, it took some time to understand how to create custom resolvers outside the ones generated by the graphql transformer. So this post will go over how to set that up.


Prereqs
  1. Amplify cli has been added, project has been initiated and user IAM has been configured
  2. Create or import api with “amplify add api”. If importing a backend, go to the amplify console and import the backend using the displayed command
  3. If backend has not been configured, connect to the aurora data source with “amplify api add-graphql-datasource” . you should see your existing database and follow the prompts for import. The appsync transformer should automatically recognize tables and types and convert them to a graphql schema. Run “amplify codegen your-api-id” to regenerate the src folder with the correct query and mutation types.
Outline
  1. Add graphql types to schema.graphql
  2. Create the req.vtl and res.vtl files
  3. Link the files in CustomResources.json
  4. Push!


OKAY, lets get started.



Step 1: Add your new type to the schema.graphql file

For example, if we were adding a resolver to get a user from our database, the schema would look something like:
type Query{
  getUser(input:GetUserInput!): User
}
input GetUserInput{
  id: Int! //what you are querying on
}
type User{
  id: Int
  name: String
  age: Int
}


Step 2 — Create the req and res vtl files under backend/api/resolvers

In amplify/backend/api/resolvers (NOT the build/resolvers folder), create two files of the format QueryType.fieldname.req.vtl and QueryType.fieldname.res.vtl. For our example above the two files would be Query.getUser.req.vtl and Query.getUser.res.vtl.

The req.vtl file generally will always look like this:

{
  “version”: “20180529”,
  “statements”: [“SELECT * FROM yourDBname.user where id=$ctx.args.input.id”]
}

The res.vtl can be as elaborate as your VTL skills allow, I generally go with something that looks like:

#set( $output = $utils.rds.toJsonObject($ctx.result) )
#if( $output.isEmpty() )
$util.error(“Invalid response from RDS DataSource. See info for the full response.”, “InvalidResponse”, {}, $output)
#end
#set( $output = $output[0])
#if( $output.isEmpty() )
#return
#end
$utils.toJson($output[0])

The response format is dependent on the shape of the data being returned. In this exmaple, since we are returning a single object the shape of the response is [0][0]. If the response was an array of objects from a list query the shape of the response would be [0]. If our query was a mutation and we were both updating and returning an object from the database the shape would be [1][0].
See the documentation for details on this: https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-rds-resolvers.html.




Under amplify/backend/api/stacks/customresources.json, add the following inside the “resources” object:


Alt text


Following our example, the object would look like:


Alt text

Make sure to use your DataSourceName

Do this for each custom resolver you wish to add.



Step 4 — Push

After you save, run “amplify push” and accept all questions, then you should be good to go!

Feel free to reach out to me on discord for any questions -> alden1422



Some Notes