Without data, you can't query for data 🤔
You can add data source resolvers to your GraphQL API in the AWS console, but in this lesson, we'll be doing it all in our CDK app. This is in adherence with the infrastructure as code best practice.
We'll create a lambda function entirely within our CDK app. We'll create a data source with our AppSync GraphQL API and add our lambda function as the handler. Then we have to make sure that data-source is invoked when there is a query to listBooks
Tomasz Łakomy: [0:00] Our API is still far from perfect, because I'm not able to access any data. In order to actually fetch data whenever we try to list all the books, we need to add a data source.
[0:10] Let's navigate back to the AWS Console. If you go back to our API and on the schema page, we're going to see, on the right-hand side, that there is a list of resolvers. Right now, there are no resolvers attached to anything in this API.
[0:24] For instance, we have this query of listBooks. We can try to attach a resolver to it. We can see that there are currently no data sources for this particular query. That is why we are always getting a null over here. I could just click over here and add a data source.
[0:41] There's a number of possible data sources that are supported by AppSync. For instance, we could fetch the data from my DynamoDB table, AWS Lambda function, or any HTTP endpoint on the web. In this course, we're going to play with AWS Lambda resolvers. We are not going to use the AWS Console in order to do that. Instead, we're going to stay in the CDK Land. The reason for that is that we would like to be consistent and always follow the best practices of using infrastructure as code, as opposed to clicking in the AWS Console.
[1:12] In order to use a Lambda resolver, first, we need to be able to create a Lambda function. To do that, open up the terminal. Run npm install @aws-cdk/aws-lambda in order to install the AWS Lambda construct. Next, let us import it. I'm going to import everything as lambda from "@aws-cdk/aws-lambda".
[1:31] I'm going to go over here and create a new Lambda function. I'm going to call this one a listBooksLambda. It's going to be a new lambda.Function. The first argument is this. The second one is "listBooksHandler". It takes a couple of arguments.
[1:46] First of all, we have to specify where the code for the function is. This is lambda.Code.fromAsset("functions"). This is the place where are we going to store all of our Lambda functions. Next up, we have to specify a runtime. This function is going to use a lambda.Runtime.NODEJS_14_X.
[2:05] Lastly, we need to specify a handler. I'm going to call this one a "listBooks.Handler". Now, we have to implement this function. Let me go over here. I'm going to create a new folder which is going to be called Functions. This name has to match this one.
[2:20] I'm going to create a new file, listBooks.ts. Inside of it, we're going to implement the body of our listBooksLambda function. For the time being, I'm going to paste in a body of a function, which always returns a list of two books with an ID, title, completed, rating, and some reviews.
[2:37] With that implemented, let me go back to our stack. We're going to connect this Lambda function with this AppSync API. To do that, we're going to create a data source, so const listBooksDataSource, and this is an api.addLambdaDataSource.
[2:52] There are two arguments here. First of all, I'm going to assign it an ID of listBooksDataSource. The second argument is the Lambda function that needs to be attached to this data source. In our case, this is the listBooksLambda, so let me just copy and paste that over here.
[3:06] Lastly, we need to make sure that this data source is going to be invoked whenever we send a GraphQL query to list all the books, such that I'm going to create a resolver.
[3:15] This function takes an object as a argument. First argument is the typeName, which I'm going to set to Query. I'm going to set the fieldName to listBooks. What that is saying is that whenever there's a query to listBooks, I would like you to use this data source, which in turn is going to call the listBooksLambda, which in turn is going to return those two books.
[3:38] With everything connected together, let us open up the terminal and run cdk diff to understand what are we about to deploy. There's a number of things here, but the most important ones is that the listBooksHandler function is going to be created. Also, we're going to have an AppSync resolver as well as a data source. Let's deploy it.
[3:57] To do that, run cdk deploy. Before we can deploy, because we are allowing an AppSync API to call a Lambda function, CDK double-checks whether we are OK with all of those changes. We definitely are, so I'm going to hit Yes and hit Enter.
[4:12] The deployment was successful, so it's time to test that. I'm going to navigate back to GraphQL Playground and hit Play. Success, we are getting a list of two books. Notice that because we're using GraphQL, we are getting only the fields that we asked for and nothing more and nothing less.