A Beginner's Guide to GraphQL | Build an API using AWS Amplify and AppSync

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
i have a confession to make i used to hate graphql eventually i came around to it and in this video i'll tell you why in this video we'll start from scratch with graphql so why it's important why you should use it maybe when you should not use it how to build a graphql api how to query with it and then how to integrate it into your own app you'll build a basic recipe app to show off your new skills before we dive into the code i would so appreciate if you left a like on this video so other people can find it and if you subscribe to my channel so you can see my next videos let's dive in i first used graphql on a project right after its launch in 2015 and to be honest i didn't really understand why we were using it but over the years i've really grown to love graphql and so i'm going to be chatting about what it is now a couple of vocabulary terms though that you'll probably want to know before starting this tutorial is a schema which is a representation of how data is structured and fields which are attributes associated with a piece of data also if you're new to apis in general i'm going to link a tutorial to that first as well as what a rest api is specifically and also i'm going to be using react to make some of the front end code a little bit quicker to write you don't need to know react in depth or anything like that but if you want to skim a react post i have one linked as well there's also a couple of videos on my channel too so what is graphql well according to its documentation it's a query language for your api and a server-side runtime for executing queries using a type system you define for your data so graphql itself is a specification meaning that there's a document outlining what graphql queries look like and how client server interaction works with it however it can be used with any programming language or data layer for your app so you can use different types of databases including sql nosql graph databases you can also use go to build an api or python or javascript or you can use the managed service which almost does that part for you so in practice this allows front-end developers to send queries asking for the data that they need including nested data to the back end and it allows the backend developers to create one endpoint that's type safe instead of the many needed for a rest api so you can send mutations to change data and queries to retrieve data all to one place so why would you use graphql there are quite a few reasons here and the first is that it simplifies the communication between front end and back-end developers so if you have a front-end team and a back-end team a lot of times the front-end developers will need to say hey back-end devs we need this data we don't have access to it right now and then the back-end developers will need to build a rest endpoint in order to give them that data back and then their requirements change and that is a whole another process again and gets even more complicated if multiple front ends require the same back-end data and so with graphql what you could do instead is just change your query or your mutation again mutation is to change data query is to get data essentially and it's going to make it so that your friend and developers can get exactly the data that they need they don't need to get all this pieces of data that they don't actually need for the app or they're not missing any fields that they might need as well they can really customize these queries to do exactly what they need rather than relying on the back end developers to build all of that out for them so sends friend and developers can request nested data using one query this will also limit the number of network requests that you need to use and those are often pretty expensive and you can add load time to your app so for example with graphql you could query for a blog post but also get all of those post comments in that one query instead of doing a second request to get the comments after you get the blog post this will also reduce the amount of front-end logic needed and maybe make that code easier to read graphql also enforces a typed data schema so each item's fields will have to match those types this makes data more consistent and manageable so instead of having to loop through each blog post and figure out if it's a string or a boolean for each title graphql will enforce that each title is a string so we've talked about why it's really good but maybe it's not the best in every single use case and that's true for any technology ever there are pros and cons to them and there are different use cases where they're awesome and when they're not so i started using graphql way back when it came out when which was roughly in 2015 and i hated it which i alluded to a little earlier on in this video i was a full stack engineer on a small team and building the back end was more work in order to build this graphql epi rest apis have been around for a long time and building one out in many programming languages and frameworks is a pretty well documented straightforward process whereas graphql was a little bit newer and i had to figure out more myself in addition on the front end you need to be more verbose to write all these queries to get exactly what you need instead of just providing a url which you would for a rest api request in addition a lot of these frameworks and libraries might be a little bit less mature for graphql just because it's newer and so you may not have to do a little bit more work if you're building a graphql api especially on the back end yourself but graphql really shines when you're working with these larger teams where one's developing the client side and a separate team is working on the server side and in addition there have been more and more managed graphql services so hasura and aws appsync r2 we'll be using aws absync in this tutorial these allow you to generate a graphql backend using their services so you don't need to write quite as much code and so graphql shines here finally many developers are taught how to use and create a rest api from early on in their careers may have been doing that for years so there may be less institutional knowledge around graphql so getting a full team up to speed on it might be an investment that you want to consider it's not wildly difficult to learn but it is something that people do need to pick up and so something to think about let's actually dive into the code which will be the fun part and i'm going to create a react app again i'm doing this because the setup will be a little bit quicker than a vanilla javascript app so i'll call it graphql playground you'll need node.js installed for this just as a quick note now we'll cd into that project we created and i'm going to initialize aws amplify this will allow us to provision a lot of these resources so amplify init note that you'll need to have the amplify command line interface installed and i'll link to a tutorial on how to do that so now you want to enter a name for your project i'll just use the default one and then it'll infer a lot of things about my project like i use vs code and react i'm going to go with this configuration and then i'll use my aws profile now that that's done running i'm going to run amplify add api it'll ask me if i want a graphql or rest api and i want graphql i will pick the default here i will use api key i'll just press enter and enter and then no i'm done i do not have a graphql schema but i will make one with one to many i do want to edit this now and open it in vs code so you'll see that the graphql file schema.graphql was created in backend amplify right here and amplify does this where it just generates a bunch of code for you so you don't need to write it yourself let's go ahead and walk through this code that was generated we're going to change it out we're going to build a recipe app ourselves but let's dive into this blog right here so type right here this word is used to represent a type of object that you might get back from your api in this case a blog we also have the post type and the comment type then this is the name of the type so blog post and comment are our names so the add sign in graphql defines a directive which means that a field or type has some custom logic associated with it and amplify provides quite a few of these one of which is at model this makes it so that the data for our blog is stored in our database then we have three fields id name and posts you can see the other fields for the other types below as well we also have types defined for our fields so our id will be of type id name will be of type string and posts will be made up of posts you'll also see that some of them have the exclamation point after them and that means that they are mandatory fields or non-nullable that means that there always needs to be a value here so we always need to have an id and a name for their string but for example you might want to have content be an optional field so you could do content which is just a normal string without that non-nullable option these types id and string are called scalar types which means that they are singular pieces of data so each blog post will have one name or one id but we also see that post is an array field so this will make it so that each blog can have an array of posts associated with it which makes sense it also makes sense that a post might have many comments associated with it and you could also do this with scalar types so if i wanted for some reason for each blog to have multiple names i could do something like that and that would make it so that each one would have multiple strings or multiple names that are strings in this case post is referencing this post right here and we also have another directive and this one is connection in this case it allows us to relate one model to another and you'll need to provide some data to it for a one-to-many relationship so one-to-many is where one object owns a bunch of other ones in this case each blog will have multiple posts associated with it so that's a one-to-many field in this connection we need to provide the by blog key name and the field which in this case is id you can see that this by blog is matching up with this by blog right here and this id will match up with this id on blog and we're referencing the id field you'll see that on the post there's this at key and that will match up with this connection here it will define how that relationship ends up working behind the scenes there is an index that's created and an index is a data structure that allows a database to look up fields faster by some sort of metric so in this case we're making it so that you can look up posts associated with the blog much more quickly than you could otherwise so the name of that key will match the key name here so this by blog will match that and you'll need to define the at key when you have a one-to-many field and then you'll use the key name to reference it you can also see that each one of these posts is going to have a blog id associated with it which will refer to the blog itself and then also do a connection based off of the blog id field which is right here so we want to actually clear all this out and create our own schema now that we talked about this so i'm going to go ahead and clear that out i'm going to create three different types so the first one is going to be recipe and i'm going to make it a model so it'll be stored in the database i'm going to do the same with ingredient and instructed so if you have a recipe you'd have a set of ingredients associated with it and a set of instructions and that's what we're modeling here so then we want to add our fields so i'm going to start with an id on each of them we want each one to have some sort of unique identifier on it so that we can see them or get each one as needed then we want to have a name on the recipe and we'll make that a string that's required here our ingredient is going to have a name which again requires string and a quantity and i'm also going to make that a string just so that we can do something like three ounces instead of just the number three because that won't be very clear so you could do number as well in graphql but it would just make it so that you can't say like three gallons it would have to be just the number three so i'll go back to string there and then info which will be a string so now we have declared the models and their fields and now we need to connect our models so we'll want to make it so that recipes each have ingredients and instructions so we'll start off with adding the key directive to the ingredients and the instructions so i'm going to actually do the same exact one on both of them and then each one is going to actually need that recipe id field that i'm referencing here so i'm saying that i'm going to look up which recipe it belongs to based off of the recipe id field that recipe id field does not exist yet so i need to add that so i'll add that to both of them and then the other thing that i want to do is actually add the recipe field which will be the object instead of just the id so it will say that each ingredient is going to have a recipe that it belongs to and then there will be a connection and then will be there be a connection and that connection will be based off this recipe id field so the final thing that i need to do is i need to add the connections from the recipe to the ingredients so we want these to map both directions so that we can get the ingredients and instructions from the recipe and if we get an ingredient instead we can get the recipe that it belongs to so that can go in both directions there that's why we're doing this so i'm going to create ingredients and then do ingredient and i have a connection where key name is by recipe to match this right here and then the fields are going to be id and i'm going to do essentially the same exact thing but for instruction oh spelling that was a little bit messy there okay so now we have our full data schema so we've got the recipes each recipe has ingredients and instructions related to it and if you ever mess this up i often have to try this out a couple times with all the relationships so you're not alone if you have to attempt this a couple times so i am going to now go ahead and deploy this and so i want to deploy this to the cloud right now it's just local so i'm going to push this by running amplify push dash y the dash y will just make it so that you don't have to answer a couple questions that pop up like you don't have to confirm oh and great i have a syntactical error i have a price here okay so i need to put this in an array there and then i need to run amplify push dash y see syntactical hairs happen to everybody and i did recipe id twice on here see this is this nice thing about having this thing that checks your schema for you i'm getting all these error messages gotta love your error messages they help so much now that that's been pushed it's deployed in the cloud and you can access it in the aws console by running amplify console api and i'll say graphql so we are going to be able to write some queries and mutations again queries to get data mutations to change data right here in the browser and this will allow you to visualize what graphql queries will look like we'll then actually integrate this into a front end of an app so it's not just hypothetical testing these things out so first what we're going to need to do is we're going to actually have to create a recipe so if i go to this drop down i can change to a mutation and i'm going to click the plus right there and i'm going to say create recipes so there's this drop down for that there we're going to create the check box next to name here and you're going to input a name for your recipe so i'll do mac and cheese i have this as a side at dinner last night it was so good so i am going to go ahead and run this now by pressing this bright orange button here and you can see that i actually got the id back of that recipe so it successfully created one for me so that's how you create a graphql mutation we are going to now do a query so i'm going to go over to query right here and we are going to then press that plus button again and here i'm going to say list recipes and i will choose my items so i'll do name id you can even see the ingredients with the name maybe and then we can run this query and so you can see that we can get associated information i did not add any ingredients to my recipe at all yet so do not worry if that's that's missing so if i run this query now you can see that i get mac and cheese back i get my id for it and then i get my ingredients and my items um i'm going to sub in a new new meme for my recipe here so maybe i'll do mashed potatoes and i'll run that mutation there and then if i rerun my query you'll see that we now have two items there and there are different queries that you can run but my challenge for you is to pause this video now and create a few more mutations that will allow you to create some ingredients and some instructions and then rerun your query to see all the ingredients and instructions that you got i do also want to break down the anatomy of a query i guess so for example here is a query the word query defines that it is a query operation that we are performing with our data so query is to get data mutations to change data you'll also see a subscription and we'll do that at the end of the tutorial that allows you to subscribe to changes in your data so if you want to refetch your data once a new recipe is created you could do that maybe you don't need to build a real-time recipe app in real life but we all have those use cases at work we need to update a page dynamically or whatever so we'll use all three of those in the rest of the tutorial and then my query is the name of the query so in real life you would want to name this something descriptive like list recipes instead of my query but it automatically generates that my query for you so that's why that was there and then list recipes so behind the scenes aws app sync which is the service that we're using for graphql you can kind of see at the top here it's called aws appsync it's going to generate what's called graphql resolvers which allow us to perform these different data operations so behind those scenes that's being built out for you but list recipes essentially allows you to do what it sounds like list out your recipes and then items this is a syntactical representation that we're going to get multiple recipes back and then we have neem which is one of our fields id which is another one of our fields and then ingredients which are associated with our recipes so you don't need to perform a separate query to get your ingredients you can just nest them like this you know that each one of your recipes has ingredients and then you do items again to say that we're getting multiple ingredients back and then you can get their fields as well uh created that you'll see some other fields in here too like created that and updated that those are added in automatically for us so you don't need to worry about that you can select them if you want though or use them for whatever you need in your app if you need to like sort by create a data or something like that those are accessible for you you can add or remove whichever fields you want to so if i don't want to see the id i can remove that from my query and then you'll see that we just get the name and the ingredients you can also add more to them and that's the real beauty of graphql is that you can update what data you get based off of just these queries instead of having to rewrite an endpoint or anything like that so some queries will also require arguments if we go into list recipes you can see that for example we can get a limit of 10 or 1 or something along those lines and that would be good so that we only get one recipe back you can also add in different filters as well so you only get ones that meet a certain condition and you can also do pagination as well so that's what the next token is for and so this allows you to again really choose what type of data that you get back instead of having to implement that all yourself you'll also see that some of our queries will require arguments to them so for example in this case the my mutation here needs to have a dynamic name in here and so a lot of times you'll actually pass in arguments and you'd pass in the id that you want for example or you would pass in the name as a variable instead of it being hard coded as mashed potatoes and that's something that you can do with graphql as well you'll see a lot of times that they use dollar signs so name is name for example and then here we will do name set to string and then down here in this interface you can provide variable names so you can say name is set to it's a new new name of a recipe muffins then we can run the mutation and then we'll run this list recipes here and so you can see that the name was created that way instead so that's a pattern that you'll see again in graphql so you're providing an argument instead of each recipe you having to provide the name right there you would pass it into the query so that's a little bit of a brief on graphql we have created a schema so far we've created mutations and queries what we're going to do now is actually implement this into a front-end app so instead of just hypothesizing about this we're actually doing it for real so i'm going to go ahead and open this up in my text editor i'm going to go to my app.js file right here and i am going to import the use effect from react and this will just allow me to run a graphql query when the component loads i'm also going to import config from aws exports okay so if you go into that aws exports.js file you'll see that there is information in here already so the graphql endpoint is the location where our graphql api is hosted in the cloud so you'll see it's in ews and then it also has your aws region and it also says that our authentication type is api key it's like a public api key where everybody uses the same one so in this case it's like this da2 thing right here don't try to hack me i will deactivate this after the tutorial don't worry not that you actually could from that anyways unless you're just adding a bunch of data to it or something like that okay so the first thing that i'm going to do is i'm going to do this using vanilla javascript so i'm just going to create a fetch request directly from here i want to show you how to make a graphql api request without any additional libraries so i'm going to create a use effect here and again for people not familiar with react this is just going to make it so that it runs on component load so i'll pass an empty array which will make it so that i don't have an infinite loop essentially and i need to have a function inside of here so that i can run asynchronous things so i'm gonna call it pull data i always call it full data i should probably use something more descriptive but that's okay so i'll do pull data here to call that function and then i'm going to make a fetch request so if you've ever made a normal fetch request in vanilla javascript this is exactly what we're doing nothing is really changing from that so let data equals wait fetch and then we need a url to point the fetch request at so i'm going to do config.ews appsync graphql endpoint i'll use intellisense for that instead of typing it out myself because i will most likely misspell something so i'm pointing this fetch request at that end point and then i'm going to do a configuration object right here to provide more information so i need a method for my request i'm going to say post a lot of these requests will have additional information with them uh specifically the query so it'll be a post request and then i'm also going to have some headers so that i can include that api key to send the request so i'll do content type is application json and i'll do accept application json and then my x api key will be config.aws absync api key so instead of just copying and pasting that out i'm using them from that configuration file and importing them from there and then what i'm going to do is i'm going to do body so this will be the request body and i'll say json.stringify and then inside of there i'm going to provide a query and that query is i will add in the query that i created back in that visual graphql interface so i have this query like my query again i should name it something more descriptive but there's list recipes and then the items id all of those types of things and so i'll run this on page load then what i need to do here is i need to do data equals await data.json i did a const instead of a let there so i'll make it so that i can overwrite that and then i will do log that data okay so i'm going to run my react server right here so i have my create react app here and you can see that when i open up my javascript console i have this data list recipes and then i have items so there's three items right now we have the mac and cheese the mashed potatoes and then the muffins so that's how you create a graphql request with just a fetch request but you can kind of say that this is a little bit clunky it's a lot of code you have this full query out here and you could abstract this out but it does become a little bit less elegant than one might want and so we're going to use some libraries in order to do this there are different options so you may have heard of apollo we're going to use aws amplifies for this but um there are different options here you're not locked into anything so i am going to go ahead and write in here run npm i aws amplify and this will install the libraries that allow us to make these requests while that's installing i'm going to go to my index.js file right here and i'm going to import amplify from aws amplify and i'm going to import config from the aws exports file and then i'm going to do amplify.configure with that config data and so this will make it so that your amplify app is using all that information from that aws exports file throughout your app so instead of having to specify that endpoint that graphql endpoint or the api key amplify will infer that for you so i'm also going to take you real quick through this graphql folder so if you see in here there's mutations queries subscriptions and if you open it up you'll see that there are all these pre-generated queries for you so amplify does what's called code gen or code generation and based off of your graphql models it will actually create these queries for you so you now know what makes up a graphql query but this will allow you to run them without having to create them yourself which is pretty nice so those are pre-created you also have the mutations for common actions and subscriptions as well so now we're going to head back to this app.js file here and i am going to import a couple things from that ews amplify library so it'll be import api from aws amplify also we'll want to import some of those generated queries so the one that i want to use is list recipes so i'll do import list recipes from the graphql queries file and then what we're going to do is we're going to wipe out this fetch request here it's a little a little long so i'll go ahead and delete that and i'm going to replace that code with the following so i'll do const data and this time it's going to be elite api.graphql and then we need to provide a query to it and inside of that it will be list recipes so we're just providing what query we want to run you could also do a text query here so if you have something specific you can write out your own query and just put it in there as a string we're just importing it from a different file in this case but you could provide it however you want and then once that's done we'll console.log that data did i spell something wrong i probably did so can't find graphql it needs to be a graphql instead of grapple okay okay so now you can see that in here we're getting the same exact data back we're just using a library to do it this time instead so that reduces the lines of code that you need to write but again if you like the more explicit fetch request you could do that as well so now we are getting all those recipes back the next thing that i want to do though is create a mutation so what we're going to do is make it so that people can click to create a new recipe so i'm going to create a button and i'll add an on click handler to it and i'll run the create new recipe um function whenever you click on that button the next thing i'm going to do is i'm going to import create recipe from graphql mutations and then i'm going to create a function here to match that name of the click handler and inside of here i'm first going to get the name from the user so i'm going to say const name equals prompt what is the recipe name and i use this wrong thing here so i need to change these curlies whoops and then i'm going to create a new recipe here so const new recipe equals weight then i'm going to do that epi.graphql again this time the query will be that create recipe but this time i need some variables with it so instead of just a query i also need to provide that name so i'll say variables and then input name and the reason why i need this input right here is if you go to the mutations here you'll see that in create recipes it takes an input right here so i need to put the name in as an input to this and you can actually create the ingredients and the instructions right in one query so that's my reach challenge for you is to figure out how to do that so now what i'll go ahead and do is i'll test this out i forgot to put text on my button so it's just a little blur you should probably put text in your button whoops so i will create a new recipe uh this time i will call it soup and then i'll refresh the page and fingers crossed we now have four recipes so muffins was created mashed potatoes mac and cheese and then soup which is now the first one so this is how you add mutations to your app so the last thing that we want to do though is you'll see that i had to refresh the page in order to get all of my recipes again and so what i'm going to go ahead and do is i'm going to create a subscription that subscribes to whenever a new recipe is created and repolls the data so in a real app you would make it so that all these display on the page and the page automatically updates with that new data so what i'm going to go ahead and do here is within my use effect here after that i'm going to subscribe to this subscription so const subscription equals api.graphql and then you'll see that we have the subscriptions file so these are pre-created for you too they look pretty much identical to the ones for the queries so i'm going to import this on create recipe here so i'm going to do subscribe here and this subscribe is going to take an object with a couple attributes on it so next which will be a function that takes recipe data and we can just console.log that and i did this wrong so i need to remove one set of curlys there and mess that up i also need to import it so import on create recipe from graphql subscriptions so now we need to make it so that we take the subscription off the page once we're done with the component so i'm going to do return subscription unsubscribe and you can also provide error to this so that something happens if there's snare okay so let's try this out and see what it does so if i create a new one now say chili and you can see that there was this value that's pre-provided with the on create recipe so you get the created at the id the ingredients instructions the name so you could go into this object and push this to your array of recipes or instead of that you could re-run your pull data function here so it just depends on your use case and how you have your code implemented in a production environment because this is far from that and we're getting to the point in the demo where i just do tests instead of that okay so now there's six different items here so in this video we learned all about graphql its benefits as well as why you may not want to use it in every single case and what those cases might be so if you want to take down your api you can run amplify delete from your command line interface and your code will persist locally but it will no longer be deployed to the cloud thanks for sticking with me through this tutorial please comment below with one thing that you learned throughout this video if you're looking to learn another new skill i'll link by a complete beginner's guide to react video on this screen thanks so much talk to you next time
Info
Channel: Ali Spittel
Views: 8,499
Rating: 4.928205 out of 5
Keywords:
Id: c2fJ7T0N1Sk
Channel Id: undefined
Length: 44min 34sec (2674 seconds)
Published: Mon Aug 30 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.