How to Create Nested and Pipeline Resolvers with AppSync GraphQL- Serverless SaaS Build Series 2.3

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
do you want to learn how you can write resolvers for those nested fields inside your graphql queries in this video that is exactly what i'm going to be showing you how to do [Music] hi guys my name is sam with complete coding but our aim is to make you into the best aws and serverless developers that you can be in this video we're going to be looking at how we can add resolvers for our nested fields with inside graphql in the last video we looked at setting up all of the base level queries so we can get things such as the top level company information but if we want to get something nested like company.user then we are able to do that at the moment we're going to be looking at three different kinds of resolver we're going to be starting with the default resolver which gets a single item we're then going to be looking at how we can get an array of items or a page of items and finally we're going to look at how we can use pipeline resolvers to resolve a series of commands one after the other if we have more complex relationships as we do with our user to company relationship remember that if you learn something new in this video then it really helps me out if you give it a like as it helps youtube know that you've enjoyed it and so shares it to more developers just like yourselves so let's jump into the code and have a look at what we need to do in the last video we set up all of the base level queries so query dot and then the query name and in our mapping templates we created a lot of like get group get my user get published posts and so on and so on and if we head over into our aws console we can go into our api and if we search for queries what we can do is we can do a for example let's say a get company and on that get company i'm going to pass in a company id and i'm going to ask for the company name and the owner id if we now run this we get back our result exactly as expected one thing we don't get back at the moment is any nested things so if i select owner and i want their owner's name and user id we know that the owner's user id should be the same as the owner id but if we now run this we get a failed error saying we cannot return no for a non-nullable type that's because if we go into our schema we find the company that has an owner of user with an exclamation mark meaning if we request it it cannot be null and if we actually want to find out how this is resolved on the right hand side we have our resolvers and under company if under owner there is no resolver for things like company id and owner id they are resolved via our original query but our original query doesn't return the user who is our owner so in this video that is what we're going to be doing we're going to be going through and creating the resolvers for any of the nested things so in this case it could be owner.user or it could be company.posts or company dot groups so if we head over back into our code what i've done is i've actually set up all of these so in here i'd like to have a comment just above this section and then it's you need to put the type instead of the type being query it is the name of the ski of the model that you are adding a nested parameter on and then the field so in our case that is company dot owner and this is going to be querying the user table this is because there we have company dot owner which is going to return a user if we find that query in here so again it uses the default type dot field so if we find company dot owner and then dot request.vtl we can see this and this might look very similar to something like get my user which if i pull that up and query dot get my user pull that to up here as well we can see that it's a get item with the user id and in this case it's using context identity username but we're going to be using something slightly different because this is a nested field we can use the source and the source is the model that this is coming off so in our case the user id that we're searching for in the database is source dot owner id and if we look at our graphql source is the company owner id is an id and that should all map up so if i now run sls deploy i'm going to deploy these new nested fields and we can test them out so now that has deployed if we head over to our console again go into queries and now run the same query again so this time we are asking for an owner and now we get the owner this means that we're doing one query for the general company information and then because we are asking for the owner it then does a second query this time on the users database to get back those fields now this was one of the simplest kinds because a company has a single owner so what we're going to do now is look at the next kind and the next kind is a company having a posts page so in this case we need to go back and find our company dot posts and here we are looking for company.posts.request.vtl so this will also look very familiar as this is going to be almost identical to the request for get posts for company so this is the nested one which has all of these parameters and if we scroll down and find get posts for company what you know it looks exactly the same the only difference is in company dot posts again we're using context dot source dot company id so basically what we're doing is we're saying query the companies the posts table and say that any of find any post where the company id equals the company of that we are looking at one other thing to notice and one thing i possibly didn't explain very well last time is this scan index forward parameter so if you set scan index forward equals true then it will return your results ordered based on the sort key or range key in ascending order that means in our case they'll be sorted from the oldest to the newest that is what we want in terms of posts because the oldest post that you have scheduled is the one that is going to go out next if we have a look at company.published posts again this is going to look almost identical to the get published posts but in this case the scan index forward equals false because in terms of your published posts you want the most recent one so the one that has the highest date to become first so you want them to be ordered in the opposite way to the posts so with this we can also head back into our console and scroll down to our posts and in here i'm going to say that i want a single post but i want sorry the posts and on the posts i want the post id and the content dot text if i run this i have the company which is here i have the owner i also have posts which is then going to have an array of posts containing the post id as well as context dot text as you can see there are the three posts that i put in as mock data before showing that this nested parameter of posts is working just as expected so with the two methods i've shown you can now get a single one-to-one relationship such as a company has a single owner but you can also get an array such as a company has a list of posts or in our case a post page so those two will actually do a lot of the schema nested fields so if we have a look at our schema those two methods will do posts publish posts groups and schedules as all of these have the same method which is do a query based on the company id for that table this can also be used for things like on posts so post.company is going to be the same as company.user it's a one-to-one relationship if we go down so publish posts dot group again a single published post has a single group and for all of these that is primarily pretty similar as you're going through and creating all of your nested resolvers you may find that a lot of them are very similar and some of them are even identical for example in my case there's a lot of places where a model has the property of group so company has a group as well as that if we look at our schema we see that a post also has a group a published post also has a group and a schedule also has a group all of these are connected because they have a group id on them so what we can do is we can make our querying or make the work that we have to do a little bit simpler inside my appsync.api.ts if i go and find here so posts.group instead of doing creating a postdoc group and a published post.group i've actually created something called model.group.request.vtl and if i find that in here so model dot group so this is doing the query where we pass in a company id and a group id to get the item of group and in all of those cases the query would be exactly the same so instead of duplicating this exact file with eight different names i've given it a single name and anywhere that we need something dot group i've just manually set the request and response to be model.group.request.vtl actually done the same thing with company because both posts published posts as well as groups and schedules all have a company field on them so again i created model.company.request.vtl and just reference those this is a nice little tip to keep the number of mapping templates down a little bit and save you from repetitive work the one where things are a little bit more advanced shall we say is the users a user has a list of companies and those companies are done through the relationships table that means that we need to say a little bit more than just get companies where user id is on the company with the relationships we need to do something called a pipeline so if we scroll down to here i've added a new query which is user dot companies but this time we have to have a kind of pipeline we then also have a functions which is an array containing functions that we want to execute if we actually head over into the amplified docs we have a nice diagram showing us how appsync pipeline resolvers actually work so when you get the graphql request there is a template which wraps this whole thing together from that template you then run function one this has its own request template queries a set of data and then transforms it exactly as we have done with every other request the difference here is that response is then passed into the next request that request again has a request template can query a data source and then return the response the difference here is this response template has access to the response of this data as well as the response from the previous function so if you need to combine data sources pipeline resolvers will allow you to do that after all of your functions have run and you can have as many functions in a row as you want there is an after template which basically puts it all together and then is sent as a response to our graphql request so in our case we are doing a get companies followed by a hydrate companies and that is because in our schema with a user we can do a query on the companies using the relationships table so what we're going to do is if i find my resolver for this which is going to be same as always it's going to be just the in this case it's just going to be the name so if i find get company there we are and in here i've got my default uh checking of the length but at the top i also want to check uh the user id so if someone's passed in a user id then we want to set the user id to that argument but if they haven't passed in an argument i'm going to default to using the identity of the querier and this way we can use this for both get my companies or we could use it for get the companies of a specific user that i am requesting if we go down a little bit we can then see that this is very similar to most other queries we're querying on user id passing in the user id and that is everything if we then go into our response we're returning basically a relationships which is going to be an array of relationships and those relationships are going to return and contain the id of the company that this user has a relationship with if we go into appsync again the next one is going to be hydrate companies so now that we have a list of company ids we want to basically query the company's table hence why the data source is companies and populates the actual full company's object so if we go and find our hydrate companies there we are and in here we have some new logic so the first thing is we get the previous response which if we look here the response from here gets passed into our request template so context dot previous result so whatever is returned from the get relationships will be here and we're looking at the relationships if the size of that array is zero then there's no point querying the database because there's no relationships there are no companies so we're just going to do an early return where we say that companies is an empty array if there are relationships in that array then we want to create a company's array which is going to be an array of queries and for each relationship in that array we want to create a company query object and then set the company id to equal the relationship dot company id so that is taking the relationship from the previous query and then setting the query on the companies table to be that company id here we're then adding this company and we have to use this dynamodb map to to map values in here because of the way that the dynamodb batch query or batchget item works and sets that to be a query if we now go down we can look at the actual query so here we're querying saying the keys needs to be the json of companies and then we're going to be querying that on the companies table now because we don't actually know the id of the company's table when we are writing this as appsync creates us a relatively random id at the end of our table name we actually have to reference it here so to reference it we actually need to do something called substitutions which we if we go into the appsync api and all the way down to the bottom of the file i've added this thing called substitutions and substitutions are a way of passing values or variables into your vtl templates so in this case i'm passing in the key of companies table and that is going to reference the deployed companies table so that we get the correct name so all you need to do is make sure that this value here is exactly the same as the value within this dollar sign curly brackets so that's going to do our query and then in the response what we're going to do is we're going to say that the companies equal utils dot to json which is our standard way of formatting it as json and then it's going to be context dot result but because this was a batch it's going to be dot data and then the dot table name so again we're going to be using our dollar sign curly braces with the substitution value in here and that will return our companies which will fulfill our request the last part of our pipeline resolver if we go up is the bits at the very start and the very end so the before template and the after template so here we have to define a request and a response and for this kind of pipeline where we're not really doing anything before and we don't really need to do anything after because everything is handled within the functions we can just have a very simple pipeline so here we have the simplepipelinerequest.vt which is just an empty pair of braces because as we've said we don't actually need to do anything at this point and the response is basically just saying take the result from the final function and pass that back to the user so in our case the response from hydrate dot companies which is an object with that companies on is what we want to pass back to our users so if we save all of this again and deploy it all then once that has finished deploying we'll be able to test doing our pipeline resolvers so that so now that has finished deploying if we head over to our console again and here we can see that we have a single company id but if we want to change this and say get my user and from get my user i want to go and say that i want the name of my user and hit request we'll get that back as expected if we open up dot companies we can say in that company's array i want the company name and the company id and hit run here we can see that this user my user has come an array of one company which is the my test company with this id we can take this a little bit further and we could even say that on that on that company i want to get the posts and on that post i want to get the text and if i run this we then get the data for the user we get an array of companies for each of those companies i'm going to get a post and for each of those posts i'm going to get context dot text you could go even further and say that for each post i want to get the company name and if we run that we can see that each post has the context and company name and this is one of the great things about using graphql is that you can have this nested nature and once you develop defined all of the resolvers for each of the nested fields the user can actually go as deep as they want through all of these steps which is honestly quite a nice setup in this video we've done quite a lot this week we've set up our resolvers for every single one of our nested fields this now means we can go through the query structure and add multiple layers of requests and nested fields this is great as this opens up the full power of graphql and means that in terms of querying we're actually done with graphql that means in next week's video what we're going to be doing is actually looking at the mutations and how we can add data to our appsync api so thank you again for watching and i'll see you in next week's video
Info
Channel: Complete Coding
Views: 1,425
Rating: undefined out of 5
Keywords: AWS, serverless, Serverless Framework, NodeJS
Id: j1XghMd1X_I
Channel Id: undefined
Length: 29min 14sec (1754 seconds)
Published: Fri May 21 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.