Direct Lambda Resolver

cup ip

In the previous section, you used VTL to write your resolvers that specify how to fetch data from an existing DynamoDB table. You also have the option of skipping the VTL and calling a Lambda function written in your language of choice. In this section you will update your existing getRaces query to use a Direct Lambda Resolver.

1. Update your schema

Add the following definition to your schema.

amplify/backend/api/graphqlrealtimerace/schema.graphql

type Result {
  Constructor: Constructor
  Driver: Driver
  FastestLap: Lap
  driverId: String
  grid: String
  laps: String
  number: String
  PK: String
  points: String
  position: String
  positionText: String
  round: Int
  SK: String
  status: String
}

 type Constructor {
  constructorId: String
  name: String
  nationality: String
  url: String
}

type Driver {
  code: String
  dateOfBirth: String
  driverId: String
  familyName: String
  givenName: String
  nationality: String
  permanentNumber: String
  url: String
}

type Lap {
  AverageSpeed: Speed
  lap: String
  rank: String
  Time: LapTime
}

type Speed {
  speed: String
  units: String
}

type LapTime {
  time: String
}

type Query {
  getRaces: [Race]
  getResults(driverId: String!): [Result]
}

Here we defined a type called Result. The query getResults returns an array of Results. The Result type is made up of multiples fields, some of which are complex types. We can define a type for each of these complex types and requests specific parts of these fields in our queries. This provides a better developer experience when we know how the data if shaped.

2. Create your Lambda function.

Define a new Lambda function that AppSync will call to resolve your requests.

amplify add function
? Select which capability you want to add: Lambda function (serverless function)
? Provide an AWS Lambda function name: **raceResultsResolver**
? Choose the runtime that you want to use: **NodeJS**
? Choose the function template that you want to use: **Hello World**

Available advanced settings:
- Resource access permissions
- Scheduled recurring invocation
- Lambda layers configuration

? Do you want to configure advanced settings? **Yes**
? Do you want to access other resources in this project from your Lambda function? **Yes**
? Select the categories you want this function to have access to. **storage**
? Storage has 7 resources in this project. Select the one you would like your Lambda to access **raceresults**


? Select the operations you want to permit on raceresults **read**

You can access the following resource attributes as environment variables from your Lambda function
        ENV
        REGION
        STORAGE_RACERESULTS_ARN
        STORAGE_RACERESULTS_NAME
? Do you want to invoke this function on a recurring schedule? **No**
? Do you want to configure Lambda layers for this function? **No**
? Do you want to edit the local lambda function now? **No**
Successfully added resource raceResultsResolver locally.

Update your new Lambda function

amplify/backend/function/raceResultsResolver/src/index.js

// MIT No Attribution

// Copyright 2021

// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify,
// merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

/* Amplify Params - DO NOT EDIT
	ENV
	REGION
	STORAGE_RACERESULTS_ARN
	STORAGE_RACERESULTS_NAME
Amplify Params - DO NOT EDIT */

const AWS = require('aws-sdk')
var docClient = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10', region: process.env.REGION })
const TableName = process.env.STORAGE_RACERESULTS_NAME
const IndexName = 'ByDriverGSI'

exports.handler = async (event) => {
  console.log(`input event >`, JSON.stringify(event, null, 2))
  const response = await docClient
    .query({
      TableName,
      IndexName,
      ExpressionAttributeNames: { '#d': 'driverId' },
      ExpressionAttributeValues: { ':v': event.arguments.driverId },
      KeyConditionExpression: '#d = :v',
    })
    .promise()

  console.log(` response >`, JSON.stringify(response, null, 2))
  return response.Items
}

The function is called to resolve the getResults query. It uses the driverId argument to query the raceresults DynamoDB table and returns the response items.

3. Create your AppSync resources

When using a Lambda resolver, you do not need to write any resolver code! You simply tell your resolver to call a Lambda function.

Add the resources below to the Resources in the template:

amplify/backend/api/graphqlrealtimerace/stacks/CustomResources.json

[ 🌟 ] CustomResources.json

Push your changes:

amplify push --yes

4. Update your app

Update src/pages/Account.tsx to fetch and display the race information.

[ 🌟 ] src/pages/Account.tsx

In your app, you can now select a driver name from the drop down. When you select a driver, your app calls the AppSync getResults query which uses your Direct Lambda resolver. The Lambda function retrieves the data from your existing DynamoDB table.

app overview