Learn GraphQL in 4 Hours - From Beginner to Expert

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

How's the tutorial?

👍︎︎ 1 👤︎︎ u/Frankenstein_400 📅︎︎ Mar 11 2022 🗫︎ replies
Captions
hey guys how's it going i'm back here with another video and today this is a video that i've been waiting to post for a long time um basically this is uh the whole series that i've been posting throughout the past month on my channel where i teach you guys graphql from the beginning i just posted the last episode this week and the reason why i'm posting the series as like all the videos condensed into a single video is because i made a poll before i started the series and i realized that it's kind of almost 50 50 the percentage of my viewers who prefer to watch series that are like um a single video compared to those who prefer um to watch series that are posted like in sequence so i decided to do both and for those who prefer to watch a a big video but with all the information inside of it this is the video i am going to post now the difference between this video and all the other videos combined is pretty much non-existent if you want to check out the other videos you can check out you can check out the links i posted in those descriptions also the comments and any doubts that i resolved in the comment sections but feel free to ask any questions as well while you're going through the series because i will be answering most of the comments and any concerns that you guys have you're also interested in suggesting any other graphical topics that i didn't mention in the series feel free to leave a comment down below and i can definitely make a video about that i absolutely loved this series so i'm really excited for you guys to watch it and yeah that's that's basically it before we get into the series if you guys could leave a like and subscribe to my channel i would massively appreciate it the reason for that is because it will help push my videos for more people and i know it doesn't seem like this will cause any effect but since i started asking for this in the start of my videos it actually worked and i'm really grateful for all the support that i've been getting so if you enjoyed the video if you get any value from it feel free to do that and i would be very happy if you do so so with that in mind let's get into the series where i teach you guys who fql since the beginning [Music] [Applause] [Music] hey guys how's it going i'm back here with another video and today i decided to bring this new series this new course that i'm bringing to the channel where i'm going to try to teach you guys everything i believe you have to know in order to say that you've learned and understand graphql so i'm going to go from the beginning and i decided to divide the series in a way such that um it's not going to be very long episodes you can watch it whenever you want and i'm going to have a very established chronological order where i start going over some of the basics about the language and about what exactly is graphql and all that kind of stuff and then a transition more into actually building the stuff and finally at the end i really hope you guys will have a really good understanding of graphql and just understand when you should use it and why it is important and used by many large companies so in this first episode i'm just going to go over some of the basics and talk a little bit about graphql as a whole and also lay out exactly what would be the structure of the pro of the the course so initially as you can see um this will be the kind of the the course structure um in this video i'm going to be talking about what is graphql and some of the differences between graphql and creating a normal rest api um i'm also going to talk about other stuffs like um how to use the graphql api and i'm going to show you guys a clear example on on how to do that which i hope will teach you guys um at least some of the the basics just to get used to the language we use with graphql understand where it comes from and start understanding the very clear differences between fetching data coming from a rest api or from a graphql api and by the way this structure isn't divided by videos um the amount of videos will be chosen later on however i'll try to post um at least four times a week uh for this series so that those who are watching as i'm posting don't have to wait um a long time to get the next episode the the episodes will be pretty short as i mentioned just because i don't want to bore anyone out and i know that if i make very long episodes people might decide not to watch it because they don't want to commit to it so if i make it short and and simple i really hope you guys will be able to stay focused and get as much value as possible from each episode so i also want to talk about um how to actually create a graphql api and for that i'm going to be using node.js um javascript and um apollo server which is the library the wrapper around our api for graphql to serve graphql in our application and when we start building that um i'm going to teach you guys a lot about the actual graphql language so like um what are types queries mutations water scalers what are enums unions all that kind of stuff i'm going to try to really focus on the graphql query language because i feel like it is something that is lacking a lot in in other tutorial series around resql and youtube um and since obviously i'm not i'm not including paid courses um i want to compare this course to other courses who are which are also free so i feel like this kind of information is lacking so i really want to go over that because it becomes confusing if you don't really understand the basics of the graphql language and finally at the end of the series we're going to um we're going to fetch the data from the api we created um in react and uh with that to do that we're going to be using a very very famous library called apollo client which is used by many many large companies and it is probably the most famous uh graphql library in react and with i'm going to teach everything related to apollo climb because it is another huge topic that i feel like it isn't explained enough i'm going to be talking about um all the different hooks that you that comes with the library um all the different aspects of your on how to fetch your data i'm going to talk about caching all the kind of stuff so it is interesting i'm really excited for this series and i really hope you guys stick with me throughout this whole series if you want to jump a couple episodes you can do that too you can jump to the episode where i talk about how to create the api and how to create the node.js application or if you're just interested in learning um about how to incorporate an api into react you can just jump to the episode where i do that as well um so that's why i want to keep this series very simple and well structured so that anyone can come and watch the episodes whenever they want to refresh their their skills or just want to learn something that they haven't learned in the past so with that in mind let's start talking about um the important stuff um so what exactly is graphql well as if you searched that that question on google before you probably seen a very broad explanation probably saying something like that graphql is a query language and what exactly does it mean um for graphql to be a query language well many of you guys might have heard in the past that sql is a query language right it is a query language and that might imply and create this false notion that a graphql is something related to a database or a graphql is a database but that's that's not true at all um query languages are not specific to databases query languages are used or is a programming language used to get data may it be from a database or in graphql it will be from an api so graphql exists as a technically a layer in between your front end and your back end and the client which is the front end will use this query language to request data from the api and graphql will take into that take that thing into consideration and we'll decide what to return or what to do based on that so differently from sql or other database languages um graphql exists in between the the front end and the and the back end and usually those those query languages related to database existing between the backend and the database so that is the distinction that i really want to make because i hate going online and seeing someone asking um which database do you use to use graphql and i don't know why i've seen that in the past and the reason why i hate that is because it is something that i used to think i should see the the the letters ql at the end and think it was some type of sql database so i really want to show you guys that it isn't and if you keep that in mind that um graphql query is an api and not a database um you might wonder okay but what what aspects of like how does this differ from a normal request that you make to a rest api well there's a an interesting distinction that you need to to make which is um in graphql there is two types of requests uh technically there's a query and the mutation they're not called requests they're actually called types that exist inside of graphql but every graphical application will exist we will have these two types a query and a mutation and i want you guys to think of it this way inside of a query will exist all of the data that you you might wanna request so if you're in the front end and you want to make a request for some sort of data you're going to make a query and all of the the logic will exist inside of the queries so technically we attribute that if we're talking about for example the http methods that you're probably used to um the the get method will be specifically connected to queries in graphql so whenever you hear about a query in graphql think of a get request because you're getting some data you're querying some data that you want to receive in your front-end now a mutation is a bit different and a bit weird if you're not familiar with it just think about the notion that i mentioned that um graphql is handling data so mutations incorporates everything related to mutating the data to to changing the data so for that reason um it is the same thing as a put request a delete request and a post request um because everything like if you want to update data in your in your api you call a mutation if you want to delete data in your api you call a mutation if you want to create data in your api you call it mutation but if you want to get data from your api you call a query this is the distinction with graphql you don't need to specify what kind of http request you're making in your front end you just specify if you're trying to make a query or a mutation and graphql will know how to handle that and that's one one of the things that i really like about it because it abstracts all of this notion over here but it does it does actually have this uh methods and graphql on its core is actually either making a get request or a post request however um you really don't need to know that um just know that you won't have to worry about what kind of requests and methods you're using when you're working with graphql and one thing that i really really wanted to talk about because it is something that i used to be very confused on is as i mentioned graphql can exist as a layer in between your front end and your back-end so this over here would be the front-end this would be the api your your back-end which let's imagine it is actually a rest api it has a bunch of endpoints that you can make requests right somewhere here would it be the database and the api communicates with the database to to i don't know put data inside of there or retrieve data do whatever it wants with it what happens is graphql can exist in two ways inside of a normal application that someone is developing it can either be a completely different separate service from your backend and uh your front-end only communicates with graphql which then makes a request to your backend service or it can exist as you're back in service and i know that's kind of confusing but just know that the the front end if you're using graphql will never make a request to an endpoint in the backend it will never do that because the graphql layer exists in between them so it will always be communicating with the graphql and depending on how you want to approach your project you can either make the graphical layer be your backend or you can just separate them like this and that's what happens i believe with many big companies if they want to scale their development services they can just separate them but you'll see many tutorials online creating an express api which already incorporates graphql and that's what we're going to be doing in this tutorial series for simplicity reasons um but i really hope that at the end as well i will be able to show you guys um a little bit of this separation uh but that would be something that i will talk right at the end so that you guys can also start understanding how a project can be structured so that it it is actually separating the back end from the graphql layer and immediately you can realize that um it is a bit different right it's a bit weird it is completely different from what people are usually used to with rest because rest is just you make a effect you fetch a request um to your your api um and you request an end point you specify the method and the api just um recognizes that request and returns data or changes the data or does something with it and now when i introduce graphql i'm talking about this weird thing which is a layer that exists in between them so i understand it might seem a bit confusing in the beginning but believe me it gets a lot better and i want to talk a little bit about this specifically what exactly are the differences between a graphql api and the rest api well the first difference is that there's only one point and that that was something that i was really confused in the beginning because think about it that way you're used to creating thought like hundreds of endpoints depending on what you want to do inside of your front end um with graphical that's that's fixed and that's that's amazing you don't need to the the front end developers don't need to memorize all the end points they don't need to know what endpoint is being i need to make a request to um all of the requests will be made to a single endpoint called slash graphql so imagine you have an application which um require like it needs data from a user um it needs data from the followers um and from posts or something like that like a social media um normally if you're using rest you would probably have some routes and some end points with this structure but with graphql all of them will be made to the single endpoint which is this latch graphql endpoint and another point that is really interesting is over thatching and under fetching and what i mean by that is imagine that you have um this beautiful profile page design that i made over here i know it looks ugly but just imagine it as a website and you have here a profile page with uh like your the user like the profile pic for the user who is logged in and they have like a feed with all the posts that they've made and imagine it's something like this and in the same web page you also have to know information about like um the followers right so the people who follow this user so you need their pictures and you need their names and their kind of stuff so you have um a bunch of data that you need to manage and you need to access in the front end so in order to make that work you can do it in either like if you're using rest you can either do it in two ways and both ways have issues to it so one way the problem is that you're gonna find yourself over fetching data which is the case i have over here you can create one endpoint and you can call it something like slash user info or you slash user profile something like that and it returns literally everything it returns a json with the user id their email their name their picture a list of followers and for each follower it returns their name their picture their id that kind of stuff um and then for the posts they probably exist in a different table as well so you also need to return the list of all the posts and this is kind of bad because imagine you want to fetch just the followers but then just to fudge just to fetch the followers you also need to get the information about the posts and the information about the user and himself which doesn't really make sense because you're you're fetching more data than what you're asking for so with rest what people usually do is they separate stuff into different endpoints so if i only want to get an info about the followers i'll create a followers and endpoint and i'll just send the data for the followers through that endpoint and it would look something like this i know some of the pictures might have bad quality but um you can see like for the followers you're only gaining this kind of information for the post you're only getting the post information and for the user you're only getting the user information however this is kind of under fetching right because when you have a situation like the page that i showed previously you you really don't want to make three api calls just to get that data each request is under fetching the information that it needs for the client for the front-end so the problem is with the rest architecture we're letting the back end determine what kind of of data the frontend wants which doesn't really make sense the front end should tell the backend exactly what it wants and the back end should just serve that data and give it back to the front end so graphql kind of turns that around it allows the front end to specify exactly what they want and graphql as the language as the the layer will allow us to do it that way and we'll basically resolve everything and fix everything for us so that you're never over fatching or under fetching data with graphql you really don't you like you specify what you want so i can have all of this data over here but in the front end i can just specify that i only want the name and graphql will only return the name and you might think okay but but still the backend will have access to all of this isn't that bad well not technically the the one of the most costly things in a website is fetching the data and downloading the data in the front end so it's a lot better to just download a json with this field than downloading all of this at once so that's kind of what graphql does and if it's confusing right now don't worry we'll definitely see how that works and we'll use that throughout the series and that's basically it for the first episode um i am aware that some of the stuff that i talked about might not be very clear yet but um that's completely fine um i i just want to let you guys know that if you stick with the series you'll definitely get it after a while because we're going to be providing more hands-on examples next episode we're already going to be working with a graphql api and you guys will be able to see exactly how it works and and how easy it is to fetch data so i'm really excited for the next episodes remember that i'm going to be posting them in sequence so you won't have to wait and yeah i'm really really excited for this series [Music] today we're actually going to start um working a little bit with the graphql language as i promised in the last video um i'm going to explain some stuff like go over the basic types also go over a little bit of how the graphql schema is defined so the structure of a graphql schema and also at the end i'm going to be using a public graphql api as you can see over here um and with this api we're going to be querying and fetching data um using revql so i'm going to teach you guys the basics so so how to make like a basic um query to an api and if you're interested the link for this api will be in the description so you'll be able to go to this link over here where you can use this beautiful interface in order to make the requests so i'm just going to open this up a little bit like this so it becomes like full screen so as you can see over here um i opened up this this thing over here this website this is actually an online version of graphql playground which is kind of like uh it's a software which is kind of like postman but for graphql you can use uh postman or other api testers to make graphql queries however i highly recommend using something like graphql playground because it has a lot of built-in cool stuff that will help you throughout your way so the thing is it also exists inside of the browser and um we're going to be using graphql playground later on in the series however for now let's just use it like this um to just to test this api that i found online so before we actually start querying the api i want to i'm going to go over just some of the basics right so some of the little small things that you need to understand about the graphql query language in order to get it going so the first thing that we got to understand is graphql comes with five different um like basic uh data types that comes with the language similar to like java or other strictly typed languages um you need to def like you need to define what your fields are so there's a string there's an end for integer there's float for um like decimals um and there's booleans for um for boolean for a true or false statement and graphql it actually only exists this five types over here the id type is because cis graphql is a query language and ids are so common inside of um like databases or any kind of request they created this id type which basically is used for ids so it can be like a string or it can be a number as you can see over here uh and i just expect something that will be accepted as an id and the good thing about graphical playground as you can see is you can just hover over the thing and it will give you like a cool explanation of what it is so i just wanted to get this out of the way there's only five types inside of graphql that you can use but you can see that i actually defined a new type over here and i called it user if you're used to something like um i don't know just defining a database schema or using something like typescript you might you're probably used to doing something like this you create um basically the structure of an object and inside of it you define all of the fields that this object will have and their types and this is basically what we're doing imagine that in our api we have a user that like we have user data so with graphql we need to define a type called user so that when we make a request that returns some sort like the data for user revql knows what a user is composed of so it's very very strictly typed in the sense that you always need to define exactly what you're going to return in this kind of ways and the good thing is you define these types like this but if you want to for example say that a user has a field called friends right because i don't know imagine this is a social media and you want to say that you're you're each user has a a couple friends right so what would the field friends be composed of well each friend is a user so technically friends should be of type list of users but how can we do that because it is inside of the user type how can we use the user type inside of itself well in graphql you can do that you can just say that each user will have a list of users and one of the things you need to learn is that um if you want to say that something is a list you define the type inside of it and you use the the brackets around it now you might find something weird here so i told you guys that there was only five um basic types in graphql string id and float and boolean but you see i'm using user over here which is exactly the point of graphql you're supposed to use those basic types as part of your other types that you create and then you can nest types that you create inside of each other so i used user inside of user and the good thing is when we access this friends field we will have access to all of the other fields that each user has so we can see if each friend is married we can see the height for each friend we can see the age the name all this information exists inside of each type so we can also um access types and nas types that are different from each other so for example uh we'll create here um a type called um video and imagine that this is youtube all of a sudden and we have a social media where you have a user and you have videos that you post so the user type might have over here a field called videos posted and by the name of it it should be a list of videos so we need to define our video type so in our video we can have an id which would be of type id um we can have a title which would be of type string and for now let's keep it simple let's just add a description which would also be of type string so what we can do is we can just come over here and do the exact same thing we did before and just say that this is a list of video and now we have nested the video type inside of the user type and this will work perfectly because we can access all of this information now it might seem like we're just defining stuff right now because we are and i feel like it's important to go over this before we start fetching data but when we start actually fetching data from this api you guys will understand completely why um it is important to understand the structure of your data because we're gonna we're gonna be able to access all of this in a way that um i before starting working with graphql i had never seen in rest it require abstracts some stuff that would be very difficult to do with rest and i feel the need to emphasize um how good some parts of this technology are so um you can see we defined we defined this over here and one thing i also want to talk about is you might be questioning what are these exclamation marks over here well graphql accepts either a value or null so you can either give it two things either you can give it the type that we add we set a field is so if we want to query a user the what we get from the api must be a string over here and the reason why we didn't it must be a string is because we put this exclamation mark over here but if we want to make a field be optional and we want to allow it to be null we can just remove this over here an example is um in this user type i only made one of them be um allow no which is the field is married because i don't know i think in real life it might be weird to make um it obligatory for you to put the the information if you're married or not into a website but you can see that if i wanted to create a user inside of my graphql api i wouldn't need to actually put this information because it is nullable now over here for both of this information over here we have a list of friends and we have a list of videos you can see that none of them have the exclamation mark the good thing is that we really don't want to because not all user will have friends so technically for fields like this um we don't make the array be um required um it does it just doesn't make sense however we might want to make the type inside of the array be required so for example we can say that um it is not required for you to have um a list of friends it is not required for you to even have a friend but if you have a friend the user type must be provided so you put an exclamation mark inside of here if you wanted to make the array required as well you can just put the exclamation mark after the array as well but as i mentioned before technically in websites you don't need to make a list of friends required and the same thing goes with the videos posted i don't really want to make it so that every user must post a video but if they post a video we want to make the field the ti the video type be required we don't want to receive no videos so you kind of are probably getting the the gist of of a bit of like how the language works a bit of the the basic types um by the way types i've used this word in this video um we call them scalars the the types that are already primitive to to graphql so the five ones that i mentioned previously we call them scalars because they are not actually like a type composed of fields but you can create your own scalars if you want to and we're going to talk about that later on in in the series as well but now that we got the gist of this basic stuff over here let's start actually working with the api that i mentioned so in this video we're going to be working with this api over here which is one of the few public and free apis i found that uses graphql and what do i mean by that well in order to um use graphql to fetch data from an api the api must support the graphql um fetching methods so like the the the way that graphql fetches data so um either it has to be a rest api that that communicates with the graphql layer and between the front and the back end or it must be uh just a graphql api built completely using fql so you can't just go and get any rest api and use graphql to fetch the data and for that reason there are like there there's just a limited amount of pre-public graphql apis out there but there's this one over here called countries graphql api which is really nice because it's really simple for this video you can see that um it just returns informations like information about countries um and when i click on the on the link that they provided i come to this page over here which i mentioned previously it's a way to for us to test the api and it is connected to the api um publicly as you can see over here meaning that we can officially make requests to the api so one thing i want to go over is every graphql api must have something called the schema and the schema isn't the database key the same thing as a database schema because graphql has nothing to do with your database it's just a schema that defines all of the data that will exist inside of the api and one thing that is important to understand is that um every graphql schema will have a root type called query and this root type will contain a bunch of fields similar and it is a type it's called a it's a type like this um and its name will be query so this is this every graphical apis have this type and inside of here you'll have each field will be something like i don't know get users which is a query so you should list all the queries that you might want to make from the frontend to request data for the api usually don't call it like this like get users this is more common with rest apis instead what you do is if i want to make a request in the front end to get a list of users we should probably have a field in our query type called users with an ass at the end and what it should return is a list of user similar to what i've mentioned before now if we want to just query information about a specific user we can do something like this we can say that this field is user without an s at the end because it makes sense it's an individual user and what we can do as well is we can actually put um variables that are arguments to a query so if i want to query a specific user i can say that i want to query a user by id so i can say something like this id equals to um i don't know of type id and i'm just saying that if i want to query a user i have to pass an id which is of type id and at the end this query will return a type of of type user like this so i just wanted to mention this before we take a look at the schema but basically this is how you lay out um all the different queries that you might make to your api and you'll see this inside of this api because one of the good things about graphql playground is that when you connect to a public api or to any other graphql api it actually generates a beautiful layout of the schema for that specific api and if i click on this button over here i can just see the whole graphql schema defined in front of me now um this api obviously has a lot of stuff um it was actually built by by really good developers so it definitely has a lot of fields and i don't want to confuse you guys so um if you see something that you don't understand don't worry you're going to understand all of this um by the end of the series however i want to bring it to ascension stuff that i already explained to you guys so for example if we come down here down here you can see that in indeed instead of this schema there is a type called query and this query over here this type defines all the different api requests that you can make to this graphql api so you can query information about continents so apparently based on what i taught you guys this kind of looks like a query that returns a list of continents right of a type called continent that they created on on the schema you can also just get an individual content and you can see that we can pass an id a code which is of type id to get that specific continent and it returns just a single continent not a list of continents there's also other other fields and other queries you can make you can make a query to countries um to a country to languages to a language but basically you can see that these are all of the queries that you can make all the data that you can request inside of this api and um there's some minor things that i want to point out um you can see that um for some of the the fields it's not actually uh as an argument they don't actually have like um a code with an id or something like that they actually have something called filter which um you can actually define um types for your arguments and they're called inputs so if for example i wanted more than just a code to use as the the variable for for for making this request i can um create an object containing all the fields that i need to make this request and i can just create them and turn them into an input and an input is defined like this so for example um if i if i come over here close this and i just open this again and i wanted to create over here a query that returns information about a user but for some reason i need no i don't just need an id for this to work i actually need an id and the name of the user well i can do it both ways i can actually just come over here and also define the the name of the user and say that it also takes a name as a as a variable and name is a string or i can just create an input over here and call it um i don't know user input you can call it whatever you want and over here i can define id as of type id and name of as type string and then instead of passing this like this i can just pass um the input as ty as type user input and it does the exact same thing it's just a way to organize your your like your queries so with that out of the way um let's take a look at this api so as i mentioned over here we have um the following queries we can cut we can query for continents we can query for specific content we can query for countries and for languages let me try initially querying for a specific country um you can see that to query to get this uh to make this query you need to um pass in a code which is the idea of the country so like um for brazil it would be br for us would be u.s um for other countries they have their specific codes you can take a look at like the search on google like a country code for a specific country and from what i'm seeing you just pass that code and it should return a country but what exactly is a country let's take a look at how they define the country so over here they define a country as an object right a type that includes their code the name of the country um apparently native which i'm not really sure what it is um the phone which i guess it's the phone code the content to which the country is inside of um it's capital it's currency a lot of stuff right we can get a lot of information so let's try running this query how do we query information using graphql well if we have this request over here we have this api done over here all we have to do is first of all open and close curly braces like this and why do we do this the way you make queries for a schema in graphql is you basically lay out all the fields of an object that you want to receive so by default at the root of all of this we are there's the query so we're just saying what we want to get from the root query and by opening and closing curly braces like this we're already saying that we're trying to grab one of these fields over here so we specify which field we want so i want the country so i just come over here and write country now country requires an argument so i can just pass in the argument which is code and i can pass the code for this country let's try querying the us so i'm going to put us over here now country as a field returns a type that is not one of the graphql native types it's not like a string or anything like that it's it's a type that was created inside of graphql so it's a type that was created inside of this schema so in order to actually get this information whenever we have a type uh like a field that returns a type that isn't one of the basic types from graphql we actually need to specify what we want from that type so to specify we open and close curly braces again so for each field that you want to get information from you just open and close curly braces and specify which fields you want so countries should return a country type so let's go to the country type the country type has all of these fields so we specify which fields we want let me get the id which is actually called code let me get the name of the country and you can just list out whatever you want let me try to get the phone um let me try to get the capital let me try to get the currency whatever you want and if you want to run this query all you have to do is you just have to click on this button over here and it should run the query and every graphql query uh gives the a similar response in the sense that this the format of the response will include an object which um the first field will be a data um data field and instead of the data field we'll include the data that you queried so data field will always return um in the format starting from the root query this type over here um the one that i said that every graphql schema must have so initially we say that um we want to get the country from the root query so this one over here and the country type the data that was returned was um the code um the name the phone the capital and the currency because those are the ones we specified and we can get this information now i i did leave out some of the types that i that that i the country included because i wanted to point out something you can see that for example um continent as a field isn't a basic type from graphql it's actually a type called content that was created by this api so let's take a look at the the type continent well the type continent includes um a code a name and a country's field so if i wanted to come over here and say that from my api request i also want to get the continent from this query i couldn't just do it like this you say will give us an error because we need to specify what from this continent i want to get so i want to get the code i want to get the name and i want to get the countries inside of this continent oh wait but again name and code are fine because name and code are types that are basic to graphql but countries is actually a list of the country type so we need to specify again what we want for each country in this list so let's just get the name of the country and what we're going to get if we run this over here is we're actually going to get the united states then we're going to get um the cut like all the information that we had previously but now we're getting the continent filled and inside of this continent field we get the code na for north america which is the continent where the u.s is located at and then the name north america and then we get a list of countries and each country only returns the name so this is one of the good things that i mentioned previous in the previous video where you can specify in the front and in the place where you're making the api request what you're trying to get so that you only download the data that you need so if i wanted to get more i wanted to get like uh let me try to get the also the the capital for each country inside of the countries list um so let me just come over here and say capital um you can just specify capital and now all of the countries also include its capital so it's it's nice right you have all of this objects and types that are nested inside of each other and when you query information you can just get this data like this now the structure is a bit hard to get used to i understand that um it's much easier to just get used to making like a a fetch request like an api request a get request to an end point and specifying what you want in the back end what you want to send in the back end however with this it becomes so much easier once you start getting the the gist of it because over like it's just you just you're just telling graphql what fields you want and it will literally give it to you without any actual work from the back end so now uh the final thing i want to do is just a little exercise um to see if um if you guys understood completely everything um that we we explained in this video by the way i'll be responding every question you guys leave in the comments um at least into a point because i'm i really like teaching about graphql i really like talking about graphql so if you have any doubts i'm super free to answer because i'm actually really excited to help you guys with this with the series overall so the last exercise that i want to talk about is instead of querying a country let's try to go over here go to the query to the root query type again and let's query um the languages field over here so if you want to pause for a second you can see that this is one of the fields um it does return a list of languages and um there's the language type exists over here so just check it out take a look at what fields you want um and also keep in mind that there is an input over here called filter so i need to take a look at what language filter input is and apparently it's this over here but my recommendation is that just ignore this you can see that there isn't actually a exclamation mark over here which means that you don't need to pass this um variable as an argument you can just query for languages and it will return the information you need you don't need to pass an argument um differently from like if you pass for stuff like continent or country where the id is required um you don't need to actually pass anything and i would just ignore this for a second just try returning a list of all the languages inside of of this api and pause the video do that um if you get stuck don't worry i'll be here i'll be here to help you out just comment anything and i'll be able to answer but i'll show you guys how to do this in a second so if you paused um or you didn't it doesn't really matter i'm gonna explain to you how to actually do this and make a request to query the languages list so as i mentioned before inside of this over here whenever you want to make a request to a graphql schema you need to assume that it's already in the root type called query and this query type and that means that um you can just specify directly by opening and closing curly braces which fields inside of the query type you want to to to get right so over here we just want the languages field like this and again we're not passing we don't need to oh we don't need to do something like this because um this is optional and i really don't care that much i don't i don't want to specify any filter that i want to pass to this to this language so i just want to receive the list of all the languages so i can just open and close curly braces again because this returns a list of a type which isn't a scalar type called language so we go over here and we specify what we want to receive from each language so from each language i just want to get their names so let me get name then let me get the code as well over here then let me get native which i don't really don't know what it means but let's see what it is an rtl which i also don't know what that means but let's see um what it is and if this is right it should return a list of all the languages inside of this api and for each language there should be a code a name a native and an rtl let's click run and you can see that apparently this is what happens we receive a indirect response an object with a field called data and then a field called languages because it's what we're querying and then inside of it there's a list of languages and each language includes a code a name and a native which i guess it's like um maybe the native way of of writing the the the language name yeah probably and rtl i have no idea what it is but you can see that this is working and if you were able to do this that's awesome because it means you're you're starting to get at least the basics of of the graphql query language and that was my hope for this video feel free to ask anything in the comment down below as i mentioned i'll be able to answer everything um i'm here to help you guys i'm really excited for the series and i really hope this was a valuable video um in the next episodes i'm going to show you guys how to build an actual graphql api so we're actually going to be writing code and i'm really excited for that i thought it would be nice to actually present this before we get to that point um because i just feel like that would be um not a lot of people do that and i feel like um if you go directly to the code you will start getting really confused with stuff like this and i feel like if i did it this way it would have been more beneficial [Music] today we're actually going to finally start writing code in graphql and in order to start we're adding coding revql um we're going to start in the backend obviously because we're going to build uh like our start building our first graphql api and to do that we're going to be using javascript node.js and the apollo server library um those are very commonly used on technologies together um apollo server is probably one of the most famous graphql libraries out there to to to create your graphql api i'm using ojs and it has a really good community so that's why i chose to to teach you guys that a library um so what we're going to be doing is we're going to build a simple application um i'm not sure if we're going to finish everything on the back end today um remember that as the as the series continue i'm going to constantly be adding more and more stuff to the tutorials so the project might seem small now but um we'll be adding more stuff which will require a bigger complexity and we'll teach you guys more advanced stuff later on in the series as well so as you can see over here we have um like you know an empty project opened up inside of vs code and what i want to do is i want to open up my terminal um over here and i want to start by initializing a new node.js project and for those who are who don't know in order to initialize an ogs project all you have to do is you have to run npm which is the package manager i'm going to be using for the series and then you run init and it should start asking you a bunch of questions like as you can see over here you just press enter to all of them and it should generate a package.json automatically for you which saves us some time saves us some time like writing this but yeah that's that's basically what we wanted and now that we have our package.json what we need to do is we need to install a few things the first thing we want to install is um the apollo server um library so i'm going to say npm install apollo server like this and this library as i mentioned will allow us to connect um to make our api into an api that serves graphql but we also need to install the graphql package because we need it in order to write actual graphql language like to use the graphql language and and write our our definitions we need to install the graphql core package so i'm going to press enter and it's going to install both of the packages um and now that both of them have installed you can see that they are over here in my package.json and these are the the like the versions for them so if you want to check them out these are the versions i'm using then what i want to do is i want to quickly just install node 1 as well because i don't want to keep restarting um my server every time i make any changes so i'm just going to say npm install node 1 like this and while node 1 is installing let's set up over here really quickly a script that when we run npm start run start it should actually um start our application um by running the command nodemon and index.js so we're going to create a file called index.js and when we run the command npm start it should run this over here which means it's going to run node 1 into our packages so so now that it finished installing let's start by creating our index.js file so i'm just going to create over here index.js and this is going to be the entry point of our api and to get started if you're used to using um node.js with something like express you will notice immediately that um the way we're going to set up our api it's going to be a bit different we're not actually using express as you saw we didn't install the express library but in order to set up the api with graphql all we do is we first import some stuff from the apollo server library so we're going to say const equals to require and we're going to require it from the apollo server library and the one thing that i really want to import from it right now is just the apollo server instance like this so this over here is a class as you can see and it contains all of the configurations and and stuff related to configuring our api to work with apollo to work with graphql so what i want to do is um over here at the bottom i want to create an instance of this and call it server and set it equal to new apollo server like this and one thing that i want to tell you guys is um you might encounter code written in graphql that looks a bit a little bit different from what we're writing right here and it is because revql has a bunch of libraries that do the exact same thing for an ojs and also for for react as well there are many alternatives the most famous one is apollo server so that's why i chose it for this but um there's other ones that i actually have tutorials on my channel for example there's one called uh express graphql which is also very famous and if you want to check it out and use that one you can just check my video however i'm just saying this because don't worry all of them do the exact same thing and it might seem kind of weird in the beginning you might think that you need to learn all the different libraries but you really don't um after you learn one it becomes a lot easier to transition into another one and now that we got that out of the way um let me talk a little bit about um this apollo server um class that we just created right we just instantiated a new instance of this apollo server class and we set it equal to server well for the apollo server class it will actually take in two and two pieces of information um the first one is some type definitions so let's for now um just write your type definitions or type devs and the second one is a bunch of resolvers now i understand that if it is your first time working with graphql and you're following the series those two words might be kind of kind of weird i did mention resolvers i believe in the first video but um basically everything every piece of data every type that you define every query you define in graphql everything you do will exist inside of this type defs variable over here and also all of the functions that resolve those types and and do stuff like make calls to apis make calls to databases um send data back every all of those functions that does that kind of stuff will be enclosed inside of a variable and we're going to call it resolvers so what we do is right now those two variables right now those two values don't exist because i haven't created them yet but we are going to pass them over here and i just wanted to mention that this resolvers are just functions that um deal with the data so like make make a a database call to insert data into a database that kind of stuff and type definitions are similar to the stuff we did in the previous video where you define your types so i wanted to differentiate both of them and now that you kind of for now set up the server variable what you got to do is you're going to come down here and just say that you want a server dot listen so you want to tell the server to listen and when the server finishes listening this returns a promise so after the the server is actually running we just want to basically grab over here a function and this function should let's just create it right now it should just console log some information like for example it should console.log your api is running like this and a happy face and you can also actually grab the url from here um so the url in which your api is running at so if you want to do that you just destructed the object over here and grab the url and you can use that over here if you want to um we might do it like this by using backticks and then just inserting the url and doing something like at and then putting the the url over here i'm just going to put the dot the money sign and the curly braces and just put directly the url inside by the way this is white but it's because of my theme but this is a string don't worry about this it's just a string with a url inside now what happens if we try running this right here let's open up our terminal and let's try running npm start you should see initially that it will crash and the reason why it's crashing it's because of what i've mentioned earlier we haven't defined any types for our um graphql schema and we also haven't created any resolvers to resolve those data that data right so we need to do that right now and one thing that i want to do is i want to show you guys a little bit of folder structure and how to organize your graphql project so usually when you are working with a graphql project you want to hold the information related to your resolvers and your types and everything instead of a folder called schema now um i've seen this thing pattern being used um many places and that's why i use it but i i got to remember you guys that there isn't a correct pattern for structuring your folders however this is what we're going to be doing in this tutorial we're going to create this folder called schema and inside of here we're going to divide it into two files the first one is our type definitions so i'm going to call it um just type devs like this and then dot js and the other file is going to be called resolvers like this and dot js as well and now as you can imagine in this files we're going to write the type definitions and the resolvers that are going to be passed into our apollo server which will make our actual graphical api run and in order to actually resolve any data we need to create our own types so we're going to finally start writing our own graphql schema that is going to define our api so over here we're actually going to import some stuff from the apollo server library so from apollo server what we want to import is uh something called gql which is just a variable that is going to allow us to write like pure graphql code and it's going to automatically translate that code into something that javascript understands and in order to do that we're going to come over here and we're going to create a variable called type definitions like this and we're going to set it equal to graphql and we're going to open and close backticks like this and inside of here we can write pure graphql code but one thing that i want to tell you guys is that um you should see that it's kind of weird because we're writing um code inside of string templates so like inside of string instead of backticks which for many of you guys initially it shouldn't give any syntax highlighting or any code completion but for me it will because i actually have like a a library installed actually it's not a library it's an extension and the extension is called um let me just see over here uh extensions and it is this one over here apollo graphql you can install this right now and it should allow you to get to have like this syntax highlighting inside of the strings or else you will just be writing code inside of um instead of actual quotes which is pretty annoying um it looks a lot better when you do it like this so i would recommend installing this extension over here and when you do so um you can finally start writing your graphql code so in the previous video and in the first video as well i mentioned that um every graphql schema starts with one specific type and that type is called query so we technically need to do this we need to create this type called query and this type over here will hold as fields um all the queries we want to make inside of our api so for example if if we have a website and one of the um requests we want to make to our api is grabbing a list of users we might want to define a query called users over here and say that it returns a list of users if we want to get um i don't know imagine it's it's suddenly facebook and you want to receive a friends list then you might want to define a field over here called friends and um this is the only way you can actually define queries that are going to be in the frontend so keep in mind that the query type is the first level of our graph now i don't want to really get too deep into um the graph aspect of graphql which is kind of dumb because graphql is made out of graphs but um i'm going to talk about that later on in the series um you got to think about the whole api as a graph and the first level is the query type now let's think about what we're going to be doing i actually want to create a very simple application which is going to be kind of like a normal application where you have um data about users so in order for us to have data about users we have to create a type called user so i'm going to come over here and i'm going to create a type called user and to create a type you just write the the syntax like this like we did in the previous video and if you recall the way you actually define stuff like the way you define the fields for a user it's pretty simple so you come over here and you write the name of the field so a user might have a name and then you write which type that field returns so a name would be a string and as i showed in the previous video string with a capital s is a type in graphql and we do want to make this field required and as i showed before to make a field required you just put the exclamation mark at the end so whenever we either create a user or just request a user name can never be empty because you can never have a user without a name so we make it a required field um so what we want to do now is we also want to give it um i don't know a username and it's also going to be a string then maybe the user might have an age we might want to do that and for age we're actually going to be using uh ins which is another type and then what we want to do is we might want to have a nationality for example we can put over here nationality and for now let's say that the nationality for the user is of type string and the reason why i'm saying for now is because this will change later on in the series when we get into more advanced topics i'm actually going to make it so that um you can only actually pass nationalities so like actual countries instead of any random string but that's for later on in the series right now our type user can only take in this kind of information and now that we have defined the type user we can start creating queries that deal with this type so as i mentioned in the past we might want to get just a query which returned a list of all the users so let's just call it users like this and let's just say that it should return a list of the type user that we just created but right now it just says that it's returning a single user so in order to say that we want to return a list of the type user we just wrap this around with this brackets to say it's a it's an array and let's make it required as well by putting an exclamation mark like this um to say that if we want to grab the users we want we want to actually return a list we don't want this to be able to be null and if we receive a list every user inside of it can't be no so it should be required as well we're just saying that instead of the query type there is a query called users and it should return a list of users whenever you query it so this is fine um it looks really nice and for now let's just keep our api pretty simple you're only going to be able to make one query and request data about users that's basically it and that's fine what we want to do is we want to actually have some data to deal with um right now you can see i don't have any data and what my plan for this series is at least for now i'm not going to be using any actual database because i don't want to make this series be kind of weird for people who use different kind of databases if i use one database then a person who doesn't use that database or doesn't understand the database won't be able to follow so my thinking is maybe i'll just use some fake data dummy data like json and i'll tell you guys exactly where you should be making your requests to your databases and i feel like it won't impact the series that much so what i want to do is i'm going to create a file over here and let's call it um fake data like this fake data dot js and inside of here i'm gonna have a list called um user list like this user list and what i want to do is i'm going to come over here and i'm going to um add the fake data and i'm going to come back in a second just to show you guys um all the fake data done okay everyone so as you can see i did generate some fake data the list over here includes each like five objects and each object contains information about a user and as you can see the data that i put over here matches the data that the type of user we created over here um it does have a name it does have a username it does have an age and it does have a nationality one thing that i forgot to add for the user type which is kind of like a really bad thing because you should always add that in in graphql is the id type and it's enough it's a field inside of the of a type and graphql by default has a basic type called id which is um similar to a string an int and other other like basic types an id can take in either an integer or a string and it just serves as an identifier to a type so now let's save this and this is our database over here so now that we have our data we have our type definitions can we actually make this work and and tell and i actually make queries to our api well no because graphql um just having this information over here doesn't work that way because they don't actually know what to do when you make the query so as an example i'm going to come over here and i'm going to first of all export this type definitions object that i created and i'm going to say module.exports like this and set it equal to typedevs so type test and if i come to our index.js now with the type over here i'm just going to import this file that i just created so require um from the the path towards the file so it would be um dot slash schema slash type tabs like this and what we want to import is the type devs variable that we created and now it's passed on so it should be working now do you think it's going to work if i run this application let's test it out if i open this up over here it actually was already running and you can see it crashed because it still doesn't have the resolver functions and resolvers are just functions that um resolve queries that you have so what exactly do i mean by that well over here you can see we have a user's field right so we do need to create a resolver that is going to resolve this field over here so we need to say that in the side of this user's field it should return a list of user so how exactly do we do that well we can come into our resolvers function our resolvers file over here and we can start by creating a an object called resolvers which we're going to pass inside of our index.js and this object will contain all of the resolver functions that will exist inside of our api so all the functions that make calls to databases all the functions that decide what we return to the front end all the functions that actually do something in our api will exist inside of the single resolver's object and the way we define it is we first define what is the the highest level field um inside of this object so in our case it is the type query and we just come over here and we write query so inside of the query type we define all the resolver functions that will exist in as a as a sub field for the query type and right now we just have one field which is users so we need to define a resolver function for this user's type and to do that we just come over here and we can call this resolver functions exactly what i called it over here so if i call this users i like to call this function users as well and it's a function so we define it like this we open and close parentheses and we open and close curly braces and inside of here we can write all the javascript necessary to tell graphql what we want to return whenever someone makes a query called to the user's field and that means that if you have a database it is over here that you make an api call to your database to get data about users and then you return at the end the data right we don't have a database we have a file called fakedata.js so what we're going to do is we're going to import the user list that we created um like this uh set it equal to uh require and we want to require from dot slash actually i need to go back twice and then go to fake data and one thing i just realized is that inside of this fake data digest file i did export const i can't do that because i'm using modules so i actually need to come here at the bottom and i have to say module.exports equals to the user list that we just created and i'm going to close this and instead of our resolvers we can just import the user list that we have right now and instead of the users query what do we want well we did have a type called user and our field is called users so means that we want to get a list of users so where we have a list of users in our fake data.js so all we want to do is we just want to return that data so what we do is we just come over here and say user list is the things that is exactly the thing that we want to return so this over here should be working and let's just export it by saying module that exports and set it equal to resolvers like this and now we can access this inside of our index.js the same way we did with the type definitions and say something like resolvers like this and now we'll just grab this over here and it should already be passed um since it's passed um it should be working if i actually open my terminal you can see that now instead of crashing it's actually saying your api is running at localhost 4000 which is honestly amazing and if i just grab the url over here localhost 4000 and i actually try to go into one of my browsers you'll see that um this message appears which is a bit different if you're familiar with something like rest and what this says is that um the apollo server library actually has a built-in um api tester that we can use and to to use it you just click on this button query your server and it should bring us to the apollo graphql studio which is this beautiful thing over here now the good thing is it recognizes that our api is running and it actually gives you a list of all of the fields inside of the query type so we have a user's field and it does know that automatically because it actually creates a beautiful documentation for you inside of the studio you can actually check out more stuff you can look at the schema and see stuff like oh what is the type user well we created this type and it actually has a like a whole documentation for it as you can see over here all this fields we added inside of our code but if we actually want to write a query as if we were making a request all we have to do is we have to come to this operations tab over here this widget and we have to structure our query as follow first thing we write when we want to write a query is the word query now this is a bit different from what we did in the previous video and it is because depending on where you're making your request you might not need to actually write the word query however we do need that right now because we will need that when we use apollo client instead of react it uses the same format so i highly recommend just doing it like this so you write query um as your first thing then you write the name of the query you want to write so let's call it get all users you can give it whatever you want and inside of here you specify which fields you want to get remember that by default the for the first level is the query type so what is the only field that we have inside of the query type we have the users field which is exactly what we want so we can write over here users and since users return an uh like a list of the object user we do need to specify which actual fields inside of user we want to receive in a request so one of the beautiful things with rfql that i mentioned in the previous video is that you can actually select which fields you want and you can just not receive all of them if you want so so what we want for now is we actually want all of the fields so we want to grab the id for each user we want to grab the name we want to grab the um the age we want to grab the nationality and i'm pretty sure that's it and if our api is working when we click on this it should run a query called get all users and as you can see it didn't work and the reason why it didn't work is it says um there was an error and it says cannot return null for non-nullable fields inquiry.users oh that's interesting right um the reason why it's interesting by the way this wasn't intentional i thought it was gonna go the reason why this is interesting is because differently from rest graphql has a built-in error handling system so it actually gives you back the error exactly what how it is you don't need to define anything and you can see right now it just says that the message is that you cannot return no for non-nullable fields um in our api so um it's very simple to solve that we just go to our to our field we'll take a look at what we created i actually figured out um what the error was and it was pretty dumb i just accidentally for the resolvers instead of importing from the resolvers file i was important from the type definitions file so basically it was like this which obviously it's wrong so it wasn't recognizing the resolvers so now that i can save this let's come over here to our application and let me run this query again when i click get all users you can see that now it actually lists out the list of all the users we have in our application and since we specified all of the fields we wanted each user contains each field but if we wanted to just get the action the nationality for each user we can also just get the nationality for each user so in the front and the one who makes the request can specify what they want and uh i just find that really cool um and you can see that it works perfectly with our data and it only works because we have here our type definition we have our type called user inside of our query type we have a field called users and we have this field and we have a function a resolver function named users as well and you can see that this was our function is returning the correct data um now imagine that for example we saw over here that uh we said that for example nationality was a string and that it was required so by by being required we mean that it can't be null now what would happen if i made it no right so i i'm going to grab my list of data over here and i'm going to make um one of the nationalities no and let's see what would happen if i came over here and i asked for the nationality and i try to get all users you'll see it won't work because um it recognizes there that it received the no value for national for one of the nationalities and um while it has to be required because that's what how how we defined it so keep in mind when you're working with um graphical and when you're defining your schemas um yeah that's that's pretty much it [Music] if you started the series from the last episode you know that we went over um how to build uh or start building a graphql api using node.js and the apollo server library and today we're going to go more in depth on that subject and actually increase the complexity of our api so that we learn more stuff about craftql as a whole and the different aspects of the language so before we get in the tutorial if you guys could leave a like and subscribe i would massively appreciate it because it would help push my videos to more people i'm very thankful that recently we hit 20k subs and it was all because of you guys and the more you guys like my videos the more it gets pushed so i would really appreciate if you guys could do that and yeah that's basically it now let's get into the tutorial [Music] so in the previous video as you can see over here um we built the bait like the the building blocks of our um api so we have our our type definitions over here in this file and we also have our resolvers in this file we're using fake data which is this one over here it's just an array containing um like a bunch of objects containing users and um that like the format of our data the structure of our data is defined in our type definitions since we only have one field which is a query we only have one resolver with the same name which resolves that that data which in our case it just returns the data so that when whenever we want to query some data and we we specify that we want to query users it will return the data correctly and we can easily just come over here and add more fields from the user type and it will also include those fields when we make the request but that is stuff that we focused more in the last episode how do we actually increase the complexity of this schema and learn more about graphql well the first thing i want to teach you guys is um there's something in graphql called enums which is very similar to how enums work in in different languages but it's very useful in graphql because it allows you to validate data very easily so an example of an enum we might want to have in this project is the nationality field over here for a user and the reason for that is because there is a limited amount of nationalities and you only want to allow a user to make a request and include a nationality if it is actually like the name of a country we don't want someone to make a request and um add a nationality that isn't an actual country in real life so one way we can validate that and prevent them from doing that is we can actually come over here and we can create an enum so to create an enum we just come over here and write enum like this and give the enum a name i'm going to call it nationality like this um nationality and i'm gonna open and close curly braces and inside of here we just list out all of the different possibilities um for which nationality can can contain so for example in our fake data right now we have a person from canada a person from brazil a person from india someone from germany and someone from chile so to to just to be sure like just to to make this simple i'm obviously not going to add all the countries here but in the real project you probably should um i'm just gonna add the ones that we already have here in our fake data so i'm gonna add germany and then there's chile as well now you might notice that i'm i'm actually writing them in capital letters there's no real reason behind it um i believe it is standard and best practices to have your enum types um as capital letters but the problem is that when you have them in capital letters they need to match what you're passing the data so i can't pass canada like this um because it's not like it's case sensitive so that we define the the type with capital letters so the data should also include capital letters so i'm just going to change that right now i'm going to make everything over here into capital letters as well and we'll just that will work perfectly for us now i just finished putting all of them as you can see over here all of them have capital letters and you might wonder okay we created this enum but what how do we like what do we do with it well now instead of saying the nationality is a string we can say the nationality is of type nationality because now this field can only accept fields or values that equal the ones listed out over here so if we go to our api over here and we try to get the list of users you'll see that it will work now the values are all in capital letters because we changed them but the difference is if i came over here and i added something that isn't a country i'm just going to put like a bunch of letters you'll see that it won't work because the the the value that we put in our data doesn't match one of the options in the nationality enum which is very useful in graphql because the whole point of your fql is specifying the data and structuring your data and your schema in a way such that you're preventing failures like this one so now that we have like we went over enums we're going to use that throughout our application let's start um adding more complexity to our user type and one thing i want to do is i want to allow a user to have a list of friends that um that they they have in their application right so we can come over here and we can just say that um the type user has a field called friends now what will be the type of friends well each friend will be also a user so we can say that france will be of type user but again um friends is on it has an ass at the end so it is multiple friends meaning that friends should be a list of users instead of just a single user and we can do this as i mentioned in the second episode or the first one i think it was the second one we can nest like a types inside of each other's so inside of the user type i can have a field which is of type user or list of users and we don't want to make this required because unfortunately some people might not have friends so we don't want to um like we want to allow them not to have friends that's that's something that you should probably allow people to have or else that would be pretty mean so um we we just created this field but what do we do now if we go to our api over here and we add friends to the field to one of the fields we want to query you see immediately it requires us to open and close curly braces because friends is of type user so we need to specify what fields from the user type we want to get for each friend so for now let's just grab the name for each friend and the age as well maybe just those two but you'll see that if i run this query friends will be no and the reason for that is because our data doesn't currently have the field friends but it does run the query because we said that friends isn't required so it's totally fine for them not to be friends but if we try to access someone like the friends for someone who doesn't have friends it will return no so how do we fix this how do we actually add some friends to some people well for john over here i'm going to add a field called friends right and i'm going to make this a list and inside of it i'm going to add some other users that we have here in our project the first one i'm going to add pedro because pedro would definitely be friends with with john i'm also going to add um kelly over here um like just copy and pasting and for now i think that's fine let's just give john two friends i'm also gonna make pedro be friends with um with someone else let me see i'm gonna make a page will be friends with sarah so i'm gonna add friends and i'm gonna add a list and just add pedro inside of here so sarah will only have one friend now if we come over here and we query you'll see that now page row includes a list of users and each user only includes the name and the age and sarah does the same thing um but only includes pedro and i'm i hope that you guys are like i started to to feel as excited as i was when i started to realize how easy it is to to do stuff like this to to nest objects and and be able to relate stuff to each other webql has a a very specific way of handling and returning data so if you master this structure over here of um how does like of which level you start at um which fields you're querying what types you're using you'll definitely be able to work with any graphql api and your life will become a lot easier compared to how you your life was when you were working with rest in a front-end application so we just added this type over here and it definitely looks good but now what i want to do is i actually want to add a new query to our um query type we just have currently the query called users and it is cool and all but it's very simple we just have one resolver and all it does is returns a list of users um but the query i want to add right now is to get information about a single specific user and the reason why i want to do this is because um it's very common in applications like if you have a profile page this you can get information about the user by using this query and display that information in the page but also because it will teach you guys a very important topic in graphql which is the topic of um using arguments which i mentioned in in the second episode you can actually create a query like this and inside of it you can add um certain arguments that you need to pass into inside of this query to make it work and the argument that we want to use for grabbing a user would be passing the id right because usually when you want to query a user a specific user you pass the id which is the identifier and it will be able to to use that information to get the user for you so what we can do is we can specify that this field over here or this query has to get a field called id and we need to specify the type of it in our case the type would be id which is something from graphql and we're going to make it required because you shouldn't be able to query a user without passing an id but then we also need to specify what is the return type for this and as you might imagine it is just a single user like this and we're also going to make it required because if you want to query a user you should receive back a user now the thing is you don't need to make this required technically it depends on how you want to handle your data because if someone passes an id that isn't an idea of a user that is in your database or in your in your api then this will break if it is required because it will try to find a user that doesn't exist and it won't return a user now the thing is if you want to handle your data based on that error message then you can leave it like this but if you're fine dealing with null results you can you might know that like oh if i returned no it means that there was no user and then you deal in the front end with that and you figure out what you want to do with that but for now let's just make it required like this and it should be fine now we just added this field what do we do now well if we added a field into the type query all we have to do is we have to add a new resolver and the resolver will be inside of the query object because it is a query and inside of it it has to be exactly the same name as the one that we defined over here which is user so we just say user like this oh and by the way there's a couple ways of defining these functions i define the resolver function like this but one way you could do it is you can actually just use the um arrow functions like this and i'm actually preferred this way i don't know why i used the other way in the previous video so i'm going to continue using it like this for the rest of the tutorial so we're going to define a user resolver and we're going to create a function out of it like this and there's a a single difference between this field and this field over here and the difference is that this field doesn't require an argument but this one does so now i'm going to introduce to you guys um the one important topic in graphql which is dealing with the different arguments and stuff that you can grab from a resolver function and i won't go in depth on all of them i actually will only mention one of them which is the one we're going to be using right now but throughout the series i will definitely go over every single one of them so that you guys can understand everything the first one that we can grab is called parent and to keep it simple and short all it does is it gives you the value that was resolved by a parent and the in the chain of um types now i know that's confusing because especially because we don't have um an example right now in our schema that is useful for like which makes parent useful but we will definitely work with that later on and since it's not useful we'll just pass uh underscore like this because the thing is we want to access the next value in this argument chain which is called args to get ac to have access to the id that we pass in this field um so if you don't want to use the parent you just put it like this and you access args and rx as i mentioned is an object that contains whatever data the user passes and the argument of the query so in our case it will only include id so what we can do is we can access that id by saying something like orgs dot id i don't know why it was capitalized but something like this should have access to the id which you used for your query which means that in our case over here we want to return a single user with the id that was passed over here so we can create a variable called id and set it equal to args dot id something like this and then what we want to do is we want to find the user with that specific id and one thing i want to use is if you recall we're using fake data we're using this array over here if you're using a database then here is a good time to use this id to select a specific user from the database table using the specific id since i'm not using um a database i'm going to be using something called lowdash which is a library that's already installed you don't need to install anything um which allows you to very easily um like do this kind of operations with arrays instead of databases and i'm going to use it because it facilitates and it kind of looks like how you would use a database to get data so with low dash what i can do is i can for example say const user equals to underscore which is what we called this over here oh damn i just realized that i called this underscore and this is underscore over here as well um so for now i'm just going to call this parent which is fine you can call it whatever you want i'm just not going to use it um and then what we're going to use is this underscore we can just say dot find like this and with low dash it will you can specify a list over here in the first argument which in our case will be the user list and then you can specify basically what you want to find inside of this list so our list is an object so we want to find the user which has the field id equals to equal to the id that we have over here and since javascript um allows you to like if you have a an object and a key is equal to the value it has the same name so id is equal to id we can actually don't we don't even need to do it like this we can just write id and it's just shorthand notation for whenever you have a key and a value which are the same name and this should return a single object inside of this list which contains the id equal to the id that we pass in the argument of this resolver and finally what we want is we want to return this user now this resolver function looks fine to me let's look at our our terminal it seems like it's it didn't break anything now let's test it out let's see if it's working let's come over here i'm gonna comment this out by just putting a bunch of um hashtags um over here it should come in out in in graphql i'm gonna zoom in so you guys can see it better but um what we wanna do is we want to add another query and this would be let's call it get user and with this query what we do is we open it like this and when we query the the field inside of the type query we now want to query um the field called user instead of users so we say user and it knows that it requires an id so you can see that automatically using our um apollograph code studio it already built it like a whole like system um that includes the id it called the variable user id it gave its type and it just added it like this the thing is when you're acquiring information in the front end and you want to make a query to fql and it has some sort of argument this is the format that we're going to write i'm not going to go too much in depth um about this right now because we are not working with the frontend yet but um we're going to pass the value of our argument which is going to be id down here at the bottom which the apollo graphql studio allows us to to just pass it like this so we can now specify what from the user we want to receive back so let's just say we want to receive back the name the age and the nationality right and now let's query a user so to query a user you just have to specify the the id and currently i don't know the id for the users let's come to our fake data um let's get let's get rave so rave is id4 so we just pass four over here instead of no and when we run this query you see that it doesn't work because it says cannot return no for non-nullable field inquiry now you can see that this gave us an error and well it wasn't intentional again um i i know what the error was um you can see that we defined our type of our argument id to be equal to id and the type id in graphql can either be a string or um or a number if you click on this over here it doesn't even give us an explanation but yeah but id should be either a string or a number but the thing is we're specifying here that the the value we're passing is four but when we get it inside of our resolver over here we get it as a string and not as a number so when we use low dash to find the user by id it's passing of a string for the id and that's why it's not finding anyone over here because our ids are all numbers so technically to resolve this all we do is we actually say that our id is equal to um the number value of our id from our args and we're just converting our string into um into our into a number and this should should work fine um i'm gonna save this we're gonna come over here and let's try querying for rave again so if we click on this you can see we get rave perfectly fine if we try getting for example pedro we can put one over here and oh it's not pages john yeah and it works perfectly and if we want to add the friends property over here for john and we only want to get the name for each friend we can click on get user and now it specifies everything we want from the user you can see it's pretty simple um after you start working with different queries and different types becomes a lot simpler to to run your or to work with your graphql schema and it's starting to actually look good we're starting to give it um some complexity which is pretty nice now what i want to do is i want to introduce a new type to our schema which will interact with our user type and i'm going to very quickly because now you guys are starting to get used to how to create queries and stuff i'm going to very quickly um add some queries for that type as well now the type i want to add is called movie and the reason why i chose this is because i want to i'm going to create a new type in our api that isn't really related to user but you can like connect both of them in some way so for example the way we're going to connect it is i'm going to come over here i'm going to create the type movie like this and um let's think about what a movie contains like what kind of information well the first one it will contain is an id definitely because everything must have an id um then a name for the movie like this and it should be a string as well um then what else maybe here in which it was like year of publication you can call it like this oh i hate this that's a huge field but it should be uh and right and what else should we get um we should probably get something like um a boolean let's think of a boolean that is good i thought about maybe just putting like is in theaters like this um just because it's a boolean um because uh maybe a movie isn't in theaters like there are some movies who which doesn't get a release in theaters so i just wanted to add a boolean because we haven't worked with a boolean type yet so i just wanted to edit like this and now i just want to keep it simple these are all the types for our movie so how do we actually query um our movies right so the first thing we want to do is we want to add a field over here called movies which is going to return um just like the users it's going to return uh a list of movies that exist in our database right or whatever we have in our application and then we also want to have uh we also want to be able to grab a movie um by its id so i'm gonna say actually let's not get by id you know why because um maybe you don't like you don't know the idea of the movie which is different with user because usually you have access to that and you only get information about user if you're authenticated but um with movies you might just want to query information about a movie so let's actually use name so we're going to use the name of the movie as a way to get the movie so name will be string like this and what we want to do is we want to return back a movie type like this and it's going to be required as well now since we created this two fields we need to come to our resolvers and we're going to create two fields inside of a query type um one called uh movies like this and let's create the function real quick just for it and the other one will be called um movie because it's it's the other uh field that we have in our query type so i'm going to say movie like this and it's also going to be a function now i want to just to separate them i want to put like a comment over here uh movie resolvers and on this one over here let's just put user resolvers just so we can kind of keep track user resolvers um now one one thing we need to notice is we currently don't have data for for movies so what i'm going to do is i'm going to quickly create some similar to this one i'm going to create some fake data for user for for movies and um i'm going to come back in a second okay guys so as you can see i made a very quick um list of fake data about movies um by the way i didn't check any of this data so like it's the the year of publications are probably wrong but i added a movie um example avengers end game i added interstellar i added super bad and also added a fake movie called page detect the movie that it's going to be released in 2035 um just so that i can say that it is not in theaters but our list of movies is done and what we want to do is we put it inside of the same file as the user list but we want to return it um at the bottom by just putting movie list as one of the things that we return in our exports so now what we can do is we can access this movie list over here at the top by just importing movie list as well and for the movies resolver it's going to be very simple similar to the user's one we just want to return the list of all the users or of all the movies so i'm just going to return movie list and for the um for the movie field it's a bit different because it's going to be very similar to the user field we're going to have to access the rx to have access to the name of the the movie and i'm going to copy this as well because it's it's going to be pretty simple as well it's going to be very similar we're not going to get the id we're going to get the name so we're going to say args.name which is now the field that we're passing and we're going to grab the movie and we're going to use low dash to find from the movie list a field with and i actually don't need to use it like this because now we're not converting anything from string to number um we can just put name equals to name which as i mentioned previously we don't need to do it like this since both have the same name i can just leave it like this and at the end i'm just going to return the movie and you can see that if we come to our application over here and we change this over here i'm going to uncomment this and i'm going to comment the query here and we change this to get all movies and i query instead of the users i'm going to query movies like this i can specify that i can get everything so i'm going to get the name of the movie the year of publication and the the boolean saying if it is in theaters or not and if i try to make this query you should see every movie that we included is over here which is amazing it means it is working now if we want to make a query um that gets just a specific movie we can say query um get movie um and then inside of here we get the movie field without the s and you can see that it already includes movie name which is honestly amazing i love how it does everything for you and for the movie that we want to get let's just get the name of the movie the ear of publication and if it is in theaters or not and now we delete the user id from our variables down here at the bottom because we're not using we're not making the user query anymore and for movie name let's just put interstellar like this because i just want to i want to get interstellar it's it's my favorite movie of all times so when i create just for interstellar when we click on get movie you see that we get only the data for interstellar if i want to get for um pedro tech the movie it should only return data for pedro tech the movie which means that it is working you just repeatedly um do this kind of stuff and you'll get used to how like the process of your creating your graphical api works you create the field in your query type and you go and make a resolver for it now i created this type because i wanted to show you guys how can i nest a type how can i relate a type called movie into a type called user and the way we do this is we can actually come over here and add to the user type a specific field called favorite movies like this and it will be a list of the movie type like this and i don't want to make it required definitely i don't want to make it required because you might not have a favorite movie um but this will will explain a lot about graphql because think about it this way we just added a new field to our user type that includes information about movies right and that's important for many reasons the first reason why this is important is because we don't want to actually um just include favorite movies like we don't want to include movie um we don't want to include um in our fake data over here for each user we don't want to include directly our movie information so like for example i don't want to copy uh objects uh related to movies and put it inside of a user and the reason for that is because graphql is actually meant to to it whenever you have a field in a type that is of the type that is not one of the basic types you should technically create a resolver for that field um explaining how you're going to get that data so like for example we have favorite movies as one of the types for our user so in our resolvers let's actually create a resolver that is not from the query type which is what we were doing before we can actually create resolvers for the types that we created that are actually being used so instead of saying query let's actually start creating resolvers for the user type and the first resolver we want to have is a resolver called favorite movies which is going to tell the user that like whenever you want to query user and you you want to get the information about favorite movies how do we know which movies are the favorite for each user so i'm going to create a function instead of our resolvers over here for user and this function should specify which um which are the favorite movies for the specific user so what i want to do is um right now we don't have like we don't like we don't have data so we don't like we don't know how to specify that but just so to show you guys um let's just come over here and return directly some some fake data and let's say that we only want to return movies that are they were published in between 2000 and 2010 something like that right how do we do that well let's just use low dash for our case if you're using a database you can easily select um by a specific range but for low dash we're just going to say without filter and it will allow us to filter through a list we're going to pass the movie list over here and we're actually going to pass a callback function over here which is going to grab a movie and it's just going to return depending if the movie dots year of publication it is greater than or equal to 2 000. and the movie dot ear publication is less than or equal to 2010. so you can get what i'm doing right this is not you don't need to do this um i'm just doing this because i want to use it as an example i'm only returning the list of users of movies in between those ears and this is just an example we we didn't specify in our data over here um in our fake data anything related to movies inside of the user list now look at what happens when i try to query for a user um over here let me just comment this out again and let me try to query for um a specific user uh i'm gonna query for the the user that like any any user and let me try to pass and the the favorite movies field if i put favorite movies i can specify now which information about the movie i want to get so i'm going to get the name the year of publication and um if it is on theaters or not now if we run this what we should see is we should see that for the user that we get we're only getting um we're returning back for favorite movies um maybe yeah super bad and interstellar because those are in between 2000 and 2010 and if i run get user you see that oh i forgot to put user id as a variable so i need to come over here and say user id and i need to change this to be um one of the fields right so let me just get whatever user i want let me put one for john and when i click get user you see that not only we get all data but for favorite movies it actually returns correct data so we didn't put this data inside of our um users table or our users list but it still resolved and understood movie like which movies this user liked now we obviously took like a a quick um like an easy route over here because we're specifying like this has nothing actually to do with the favorite movies of the user but one thing you can do is you can have a separate table inside of um inside of your database related to movies and what you can do is inside of a inside of the the users table or whatever you can include um a list a field called favorite movies and just a list of ids and then you can use that to query data from the other table and return it over here so whenever you have a field inside of a type that it doesn't return a basic type you can actually add resolvers for that field to that type and specify what that field will return now this is kind of confusing i i honestly think so because in the beginning when i when i started working with the fql this was one of the things that made me go crazy um i hope you guys understand it um because we're gonna be using a lot more of this later on in the series and we're going to get more in depth on this as well [Music] previous episodes we built out our at least the beginning of our revql api you can see that we basically defined a schema that looks pretty nice we have two types of users um or two type two types in our application one is called type user and the other is called type movie and we also have our type query which allows us to query users and movies so um this basically taught you guys a lot it taught how to use arguments while defining queries um i also taught how to how to create an enum which was something that i i wanted to show because i don't know i just thought it would be interesting to show in this tutorial um and then we also went over how to build resolvers for those functions we're currently using this fake data list over here which um just contains a list of users um for the user list and there's also a movie list and the resolver is basically just use that list to deal with with what with the data right depending on what they want to return and we also have a resolver for the favorite movies filled inside of user which if you did if you don't remember from the last episode is important because um favorite movies is a field inside of user which doesn't return a like a basic type already existed to graphql it returns a movie which is a type we created so we do need to specify how to get the favorite movies for this user since um in our fake data over here this isn't included inside of the user list so in in the the user that we're the data for the user that we get from our single database request it doesn't include a field called um favorite movies so we do need to do that over here at the bottom um when we inside of our resolver um so in this video what we're going to go over is basically how to work with mutations which is the other root type that exists inside of graphql similar to query but as you might as i explained in the first episode a mutation it differs from a query because it is basically used to mutate the data to alter the data so if you were using http methods a query would be like a get request and a mutation would be like a like a put a post or a delete request it is used both like for creating data for updating data and for deleting data now we're still using fake data for this tutorial so what i'm going to do is if i want to add a user for example um to our electorate to our data i'm just going to push a new object inside of this user list array and that's how we're going to add stuff into the into our data right and the similar thing will be done with the other types like i'm going to show you guys an example of updating and deleting just to show you guys how you can do that and yeah that's that's basically it before we get into the tutorial if you guys could leave a like and subscribe i would massively appreciate it this tutorial series is actually getting a lot less views than i expected um but it's totally fine because i'm i'm loving this i i love teaching like more complicated topics and i feel like the reason why it's not getting a lot of views is because it's not a beginner video so um it makes sense that not a lot of people would see it and it's one it's probably one of the most worst performing series in the in my channel but it's totally fine because i'm loving it so don't worry i saw some people commenting like don't stop the series i won't stop the series until i feel like it's a good point for to afraid to end um and yeah if you enjoyed the series please leave a like because it will help a lot the channel so now let's get into the tutorial [Music] okay everyone so to start writing mutations into our project the first thing we're gonna do is similar to a query every graphql schema that wants to alter data wants to add data should have a type called mutation so i'm going to come over here and i'm just going to add the type called mutation and similar to query what you do over here is you just write the name of the fields that are going to be able to mutate stuff so for example if i want to have a field which creates uh a user i might just create a mutation a field over here called um create user something like this right and obviously uh similar to like other types in graphql you need to point out that you return something so what is commonly like the standard in graphql is you whenever you create something or you delete or you update something whenever you have a mutation with some sort of type you just return the type so if i'm going to create a user i do all the logic to add the user to my database or in this case just to my fake data file over here and at the end i just returned back the user for for the following reason um graphql deals a lot with um caching so you need to update the the data in the front end so that it is the most it has it isn't the most updated state possible and we'll go like over this more in the next tutorials but for now let's just imagine that whenever we run a mutation we've got to return its new updated values so with the create user um it's something that we want to do it's basically a mutation that will allow us to add a new user to our user list that we created now one thing that we need to take into account is how do we like know the data that we're sending you can see that each user requires an id a name a username an age a nationality for it doesn't require friends but you can see that those are the ones required and you can add those as well over here um so how do we like allow the user to whenever they make this mutation they send the data required to form a user well it's pretty similar to how you use your past ids and arguments for queries however the difference here is that it is a lot of data so it would be kind of boring to just come over here and just add stuff like oh a name um which is a string and age which is an end this would be this would make this huge right and you can do this if you want especially if it isn't a lot of arguments before creating a user you pretty much need to put a name a username an age and a nationality so a common thing you can do is instead of defining stuff like this you can actually just come over here and say that create user accepts a a user of type user and then kind of makes sense and you can make this required um but one thing i want to propose is that whenever you you you create mutations and you want to put arguments for mutations or anything that is big i would use something in graphql um called an input which basically um allows you to just like define inputs for arguments whenever you have a field so for example um we have this create user over here why don't i just come over here and say input create user input and just open and close curly braces like this and then we can specify which fields we want to use to create a user now i understand that this might seem like it's redundant because um literally what we're doing over here is we're just gonna copy and paste this over here and the only thing we're not gonna add for for the input is the the id because obviously like it's not you shouldn't be passing an id you shouldn't need to know the id whenever you create a user um but the thing is there's many practical reasons why you might you need to use an input instead of just directly putting the type as the argument over here and i'm gonna just change this before i explain to you guys but basically and there's a lot of stuff that you can use and do with an input that you can't do with the type for example um imagine imagine that this age verb over here wasn't required it was just like you just accept an integer right um imagine that it just since it's not required i can not pass like i i'm allowed to to not pass an age and this input would be completely correct i would be able to create a user now what happens if i want to say something like um this shouldn't be required the user don't need to send an age but if they don't send the age i want it to default to like 18 years old so if i want to do that i can't do that with the type because that doesn't make sense this is just the structure of the user whilst over here if i want to do something like that i can just say something like this is equal to 18 and this over here should default to 18 if um if age is not passed this is this is a little trick that works with graphql now in our case we want to make hb required and it also points out that you don't need to pass an id which is important and that's why you should be creating an input like this so now we're just going to put this over here um we already did it as an input and we're going to make it required because you should pass an input to create a user now how do we deal with this how do we go from this field being a mutation to actually creating and adding our like new data into our our table or in our case our fake data array well you can see that if i refresh my my code over here this is my api it does give me an error which is kind of weird let me go over here to my code it's saying that um oh i got an error which is just saying that um the type of create user input.friends must be an input type but got user this makes total sense and it was a tricky mistake over here you can see that we do have a friends field right we do have this thing inside of our user called friends but the thing is inside of our input we're saying that if you want to add friends you just have to pass a type user but that doesn't make any sense because we're just creating a user right so what i want to propose is when you create a user you don't pass a movie or friends we're going to do this separately so when you create a user all you need to pass is your name your username your age and your nationality which are the um like the required types and and that we created over here and by the way since i didn't specif since nationality is like not a specific type it's an enum that we created i do want to um be able to allow it to to not be passed to not be required and the reason for that is because when you're working with predefined types that are like this you need you need to account for the fact that maybe someone or for some reason passes canada but without like capital letters like this and if we make this required completely required it will only will give us an error if it isn't the correct like exactly how we define over here which is something we might want to avoid so what i'm going to do is i'm going to say the nationality is a nationality it's not required but if no one passes a nationality let's default it to brazil and yeah i'm just choosing brazil because i'm from brazil but um yeah this is just an example because i find this really cool and i just wanted to show you guys how this would work in a real application so our user input now is correct let's check you can see no errors are occurring let me refresh over here you should see that um if i just remove this over here i'm actually just going to remove this i'm going to remove the get movie as well from the last episode we still have our query over here um and it's working perfectly if we want to run a mutation um we really can't do anything about it and the reason why we we can't just run a mutation right now is because we created the mutation type over here um great user but we didn't actually write any resolvers that actually do something about it that actually gets this input and creates a user so to do that let's come to our resolver.js over here and similar to how we have a query type inside of our resolvers and we also and we have all the resolvers for the fields um for the query and we also have a user type over here for the user we want to have a like a a mutation type inside of here so i'm going to put it right below the actually i'll put it below the user like down over here and i'm just going to call this mutation and it's going to be an object which is just going to include like all of the functions related to mutating the data so the first function that we're going to work with is the one that we created has to be the same name so it has to be called create user and we're going to come over here just create the function and it should be fine now one of the things is when you create a user or when you write any mutation you'll probably you'll probably need to like access some sort of argument to the function so similar to how we accessed um like the arguments for the fields that we're requiring the required arguments we're going to do the same thing we need to get this two things over here from our function and now we can use this args to be the new user so what i'm going to do is i'm just going to say const user is equal to args dot input like this input because if you recall we created over here uh like a the argument is called input like it has a type input and this includes everything that we create that we want to use so in order to access this i can say args.input and now i get the user info that exists inside of here so now just to see if it's working or not let's just console log this like this and just console.log the user it will give us an error definitely because we're not returning a user like we said we would one thing is i'll not make this required i'll just make this not required for now and let's come over here and let's try to run this mutation to see if everything is working so in order to run a mutation you do something very similar to a query you come over here to where you're going to make the api request you're just going to write mutation then we just open and close curly braces which is a bit different from a query because we were using the name over here we could still give a name for this so i can just come over here and say something like create user um as the name of the mutation and then inside of here i tell which of the fields inside of the mutation type we're trying to access in our case we just have one field which is called create user so i can just say create user over here and you should see that it will because we're using this the polygraph called studio it will automatically generate some of the stuff for us so you can see like it generated our this parentheses over here and all of this information inside i'll just explain really quickly what they mean so when you define a mutation like this and you give it a name like create user um you first grab the the variable like the the you create a variable by using this money sign over here and set it equal to b of the type create user input and that means that now we can pass the the input data over here similar to how when you're going to make the request in the front-end you're going to pass the data as a variable to the mutation then inside of here we just say that we call the mutation and we just set the input to be equal to the variable that we created i know this is kind of confusing and believe me it's going to make a lot more sense when we start working in the front end but for now uh this just just go with the flow um we're just going to pass the data inside of this variable and it should be accessible inside of our resolver so for now let's just write something like i want to get an id i want to get the name and i want to get the age and the data i'm going to pass it has to be of a user type or a create user input which just asks us to have a name so let's just pass a name like this name i'll just make it pedro then let's pass uh age so i'll just pass age which would be 20. oh by the way this is j this has to be jason so we do need to double quotes this and let me just open this up a bit um the final one it's actually not the final one i think it's uh uh it's username so username even comes before so i'm just going to say username like this and i'm going to pass page attack and then finally we're going to have nationality which technically we don't need to pass so actually i won't pass just to see if it defaults to brazil now when i click create user you'll see it gives us no it did work status 200 it did work because we although we didn't return a user because in our resolver we're currently not returning a user we should see the data that we passed over here being console logged in our server and as you can see this is exactly what happens and it actually defaults the nationality to brazil because we like although we didn't pass any value for it so we know that it's working we know that we can access the user by saying args.input which is amazing so now all we have to do is just add this new user to our um fake data array over here or if in your case you're using any database like mysql or mobidb here's where you add a new field to your like your database table so for us what we're going to do is we're just going to come over here we're going to grab the id of the last user this is something we have to do because um we want to increment the id by one every single time so i'm just going to say const last last id like this is equal to user list and i'm going to grab the last one so i'm just going to say i want to grab the user list dot length length like this minus one so i'm just grabbing the last element and i want to grab the id from it and this is the last id so what i want to do is i want to construct i want to add to this user type that we just grabbed from the input i want to say user.id i want to add a new id to it and set it equal to last id plus 1 because now if the last id was 5 now the new user we add is going to have an id of six if that makes any sense and then finally i think this is all we need because now all we have to do is we just have to say user list dot push and we're gonna add the new user to the list and at the end we just return this user now let's see if this is working if this is working what should happen is you can see over here if i query all the users like over here i'm just gonna also remove this you should see that um there's no pedro attack um over here oh no i'm getting all the movies not users i need to grab all the all the users so i'll just say get all users and let's just query the users field over here and i'm just going to delete all of this because this was the previous query and what i really want to do is inside of here i want to grab the id i'm going to grab the name and i want to get grab the age just for now you can see that all the users none of them just one of them is called pedro so what i'm going to do is i want to add a new user the name is not going to be pedro the name is going to be elliot and the username is going to be on elliott one two three the age can be 20 as well and i won't pass the nationality again so what we're going to do is we're going to just uncomment the mutation and let's run this mutation again to see what happens you can see first of all we do get the user back because we're now returning the user at the end of the mutation and let's uncomment this and let's run the get all users again to see if the data was actually updated and you can see that it was we now have an elliott and the idea is is six and the age is 20 which means we are actually adding some data to our table now for we're just doing this very simply by just pushing it into array and if you're using a database it should be a little bit more complicated but at the same time just put the logic for like inserting to a database table right over here um instead of having to do like all of this thing over here um this is just because i'm using fake data and yeah i i hope you guys got this and this is going to be the flow of creating mutations from now on now since we went over our first mutation i just want to um go a little bit faster for the next ones that we're going to create because um it's going to be pretty much the same so for example we have a create user let's just add a update user right because it might be something that we want to do um let's instead of being update user because um should we do update user actually let's not let's not do update user let's just do um update user name something like this um so we just want to get a new username and update that user uh that users and username so to do that what we got to do is we got to create a new input over here and this input is going to be pretty simple we're going to call it update user input or update username you input like this and what it requires is number one uh an id like this because we want to get the id of the user we want to update the the username and then it also requires the new username so let's just write here new username like this and it's going to be a string and what we do is we just put input as a field and we say that it is of type update username input and at the end we should return a user like this now we just create the resolver for it um the resolver is going to be pretty simple again we're going to just copy and paste this over here what i want to do is i'm just going to grab the um the id for the user i'm going to delete this over here and i just want to grab the idea of the of the user one update by saying rx.input.id and then i also want to grab the new username by saying new username is equal to args.input. new username we could actually have done this a lot easier we could have just done something like this set it equal to args dot inputs and then just grabbing the id and the username by destructuring the object this is a little trick that i would recommend for you guys instead of having to write new lines um do everything in one of them and now we have access to the id and the new username that is going to be passed in the argument so what do we do with it well the first thing we want to do is we want to first of all find the user with this id and just change its username so for to make that i'm actually going to do it pretty simply i'm just going to grab the user list i'm then going to for each like loop through the username or the user list and i'm going to grab each user over here and all i'm going to do is i'm just going to ask if user dot id is equal to the id that we want to update then i want to say that the user the username is equal to the new username like this and this should be fine we're just looping through the user list checking to see if any of the elements in the user list has an id equal to the one that we want to update and if it is then we want to update the username to the new one passed in the arguments and at the end after everything is done i want to do this right here i want to create a variable called user and it can be null right it will initialize it like this and if we eventually find a user and actually that we want to update then we'll just set this user equal to user uh or actually uh i'll just call this user with change actually i'll call it user update it makes more sense and i'll set this equal to the user that was actually found and that has the username updated and then at the end we just return the user updated now there's no guarantee that we're going to pass in the front end an id that actually exists in our table or in our data so this over here can be no which makes sense because we just made our return type um to be not required which means that we don't really need to send something back as long as like this allows us to handle errors more easily so let's test to see if this is working let's come over here to our um apollo graphql studio um let's get all users you see everyone is working perfectly you can see elliott disappeared because we restarted the server so that's right um but one thing i want to do is i want to update the um i want to update sarah's username let's just grab username over here let's see what is sarah's username it is currently cameron um i want to update it so to do that i'm just going to call a mutation over here um i'm going to just copy and paste it like this but instead of create user i'm going to call it update username and instead of being the query user i'll just say update username uh oh damn i just realized this this got pretty confusing so i'll just delete this i'll say mutation update user like this and then i'm just going to say update username as a field and you can see it filled in everything perfectly now we specify which fields we want to get from the user who was updated i'll just grab the id i want to get the username which are the two fields that actually matter so if i come over here and i just remove the create user input and instead i put an input for the update user i need to pass an id the id for sarah is three so i'll just pass three over here then the username for sarah is cameron so we want to update that to let's make her username uh i don't know ward like this so this is the data we're passing let's try to run it um it actually didn't work because it said that the field new username required oh i call the new username not username so i need to say new username like this and now that we have the correct name for this variable over here let me just click on update username and it doesn't seem to work which is kind of weird let me just take a look at the code um i don't see anything oh actually damned i already found the error so we called we just copy and pasted the create user mutation function and forgot to change this to update username so this needs to be the same name as the the name we had for our type definitions so now that this is done if i run this you should see that we get back the data and if i actually come over here and i try to get all users again you should see that sarah now has a username award instead of whatever the username was before if i want to update pedro's username to page attack i can just come over here um uncomment the mutation again and pass page pages like id s2 and then um i'll just come over here change this to i don't know page row one two three and when i click update user we should see that it sends back the correct data and if we query all users again um it should show that both pedro and sarah has updated usernames which means it's working which is awesome and we basically are able now to update stuff inside of our data finally to keep the episodes short i'm just going to really quickly show you guys uh delete mutation which is going to be pretty simple um the first thing i want to do is just delete all of this because it's kind of annoying me that we have a lot of stuff inside of our operations like little tab over here then i want to come over here and i just want to add a new field to our mutation let's call it delete user and or i'll just say that it will return a user the user that was deleted but one thing i want to point out is that um when you want to delete a user usually you just have to pass an id right it kind of makes sense you just want to pass an id um and delete the user with that id so i'm just going to grab an id i don't even care um to create an input because um in this case it's just one field so it doesn't really matter we don't need to create mult like a hue an input type just for this so now to to finally delete stuff i'll just come over here to our resolvers add a delete resolver by saying delete user and just adding the function we do need to grab the parent again because we need to get the rx because now if i i need to get the id from this orgs by saying cost id equal to rx.id then now that we have the id um in order to remove a user with like in a list in an array with that specific id we can just just use the low dash function called remove so we can do something like this just come over here say dodge remove then say that we want to remove it from the user list and then it will loop to the user list and we'll just say that we only want to remove the users which the user.id is equal to the id that of the user we want to remove in our case um and as we did before um like the id will come as a string so we do need to convert it into a number by just saying number id like this and this should remove everything um since we're not keeping track of the user and for simplicity reasons i'll just return no right here we don't really care that much about the user that was deleted and that's kind of most like most cases this happens um but since we just returned everything it seems that we removed it from our array let's test it out how do we get this to work well what we can do is we can just come over here and say mutation and for this one just to show you guys you don't actually need to write the name of the mutation um or query you don't need to give this name this is more best practices and it's easier for organization especially when you're working in the front end but what we can do is we can just say mutation then write delete user and it will actually generate a mutation without a name as you can see over here we do say that we want to get the the field called the lead user and that we need to pass an id so i'm just going to delete the old inputs that we had over here for variables and just leave the delete user id and i want to delete the user um with the id4 rave i want to delete rave over here so i just passed four and for the user that returns back right now we're returning no so i'll just put id over here just for it because or else it will give you an error and let's try running this if i click run you should see null because we are returning though and if i try to run the get all users which by the way if you want to alternate between um stuff that you wrote in your operations tab over here you don't really need to to comment them out um i don't i can't believe i actually just found out it's because it the apollo graphql studio is actually pretty new so um i'm still pretty new to it um so i just found out that you just need to click like this and it will keep like alternating between whatever operations you want to make so we just deleted the user let's try to get our users again and you should see that rave is not here because we delete it if i try deleting kelly over here you should see that kelly doesn't exist anymore so this is amazing it means our mutations are working it means that our graphical api is pretty much like in a pretty good state right we have some cool queries we have some cool mutations we have some complicated types um we talked a lot about inputs we talked a lot about um different types that you need and how to build your resolvers like this and yeah i'm really excited for how the state of the series is [Music] in this video we're actually going to start transitioning into creating a full stack application so we've dealt a lot with um backhand stuff we we kind of know how like type definitions work we understand how queries and mutations work we understand how resolvers work and it's all chill but the thing is the whole point of graphql is to facilitate how the front end is able to query and handle data from the beckon so and it is important for us to just start working on the front end so that you guys can get introduced to that topic and if i need to introduce new topics from the backend i'll just introduce them after we already have a front end so in this video we're going to create a new folder over here and it's going to be called the client folder like this and this client folder will include everything related to the front and similar to how the server folder includes everything related to the backend so i'm just going to open this up over here this terminal is in the backend and it's running our server i'm going to open another terminal and change my directory to be the client folder like this you can see it's the client folder and i just want to install a simple react application into this project and to do that i'm going to run the command npx create react app like this and then a dot at the end which basically means that i want to create my react application inside of the client folder now what we're going to be using as our communication like library um to use graphql in our front end it's going to be called the apollo client library i'm going to show you guys um this over here apollo client this is a it's probably the most famous front-end graphql library out there especially for react and it allows you to do so many things um you can just look over here and see how you can write the syntax and how everything works um but we're going to be using this throughout our project and it is it's used in many companies so i feel like it's a good learning experience so as you can see over here um it has finished um just creating our our front end um we have this simple react application over here i'm just gonna close the back and stuff because we're gonna focus on the front end um and what i like to do whenever i start a react project as many of you guys might know is i like to delete the test file the index.css file the logo and the test file because we're not going to use any of them so i'm just going to delete all of them like this and now let's come to our index.js delete the import for the css file we just deleted and then come to our app.js and just delete um the logo over here and also all of this stuff over here because we're really not going to use it now let's just write over here hello world and try to run this application by coming over here and say npm start when we run this it should run and open it over here and it should be an empty screen an empty white screen with hello world written in the middle of it so let's see you can see yeah this is exactly what happens i'm going to zoom in a little bit just so that everything becomes clearer and what we want to build is we really don't care about like what our front end is we just want to be able to fetch data and create data right so the first thing i want to be able to do is fetch data so over here in our fake data we have a list of users and we have a list of movies and in our schema if we see over here we have a two query types we can get a full list of all the users we can get a specific user we can get a full list of movies and we can get a specific movie i'm going to show you guys how to do each of them respectively um in their own but the first one we're going to work on is how to fetch a list of of users right or a list of movies we can do both of them but it's going to be pretty similar so it's totally fine so to do that we actually need to tell our react application that it's going to accept and it's going to make a connection to a graphql api so that whenever we make an api request it is using all the graphql standard methods to make that request and fetch that data so in order to do that we're going to come over here to our highest level component which is the app.js and inside of this what we want to do is we want to initialize first by importing some stuff from the apollo client library now as you can see over here we haven't installed apollo clients so we need to do that right now so i'm just going to open another terminal over here and let's clear this terminal let's go into the client folder like this and let's start installing all the packages we need so technically the only library we actually need is the apollo client library and by the way this is apollo client version three um ever like it was very different the way you did all this stuff including like um how you import and the name of the libraries and everything um from previous versions so keep in mind that this is the most updated version of graphql or not with you all but the apollo client library so uh just keep that in mind so i'm just going to come over here and say npm install and i want to install the library at apollo slash client and this library over here is the one that is going to control our whole front end and make it work with our graphql api now as you can see over here um i pressed enter and it's installing everything and it seemed like our uh like our pro our library just finished installing so what we want to do is we're going to come here at the top and we want to try to import from at apollo client again and you can see that our um thing actually autocompletes which means the package is installed now what we want to import from the public client library is the following we first want to import an apollo client like this an appointment it's a class that is created by the apollo client library then we also want to import something called in-memory cache which is also a library and i'll explain a little bit later and then we want to import apollo provider which is also a class that comes from the apollo client library what we need to do is this apollo client over here this class it basically whenever you create a new instance of it you're creating you're telling graphql that you want to use this to connect to an api so for a connection you need an apollo client cl like a nepal client object or a class instantiated so to do that we'll just come over here and we'll just say create a variable called client and set it equal to a new version or a new instance of the apollo client um class like this and this class takes in a few arguments um and the way we pass it in is as an object like this and the two arguments that we take in is basically the first one some sort of cache that we need to specify and i'll go over this in a bit and also a uri which is basically the the link the the url to where your graphql api is running so if you're using a public api you can just put it over here but if we're using our own api for us it's basically just http slash localhost 3001 because that's where our api is running and this should it should tell graphql that this is where our api's grown is running which means that it's going to actually connect to our api and make it work so i also need to put the slash graphql because if you recall graphql always runs on the slash graphql endpoint so we need to specify which one it is so that our library understands what it's doing then for cache what happens is the apollo client library um has a really good um like state management aspect to it and it allows you as well to cache um information and data um into your your browser right so basically if you fetch some data and you change a component for example moving your in your route system and you go back you want the data to be kind of updated right or you might want the data to be the same thing you don't want to need to refresh the page every time you move because think about it this way if you render a component and you go back to the to an other component making a request every time you render a component it might be might be overkill and if you want you can just cache your data and the data will maintain the same because probably there weren't any changes to data to begin with so this is basically what cache is in in graphql and with graphql with the apollo client library we use they have an option which is basically just determining that your cache is in memory which means it's going to literally save that information or cache the data in memory so we'll just say that our cache system will be in memory cache and we can just declare it like this and graphql will know exactly what to do so now that we have this client variable over here um we we basically just declared what we how our structure of our api will be and what api we're communicating with um now what we need to do is we need to wrap all of our components that should be able to make a request to graphql with an apollo provider component so i'm just going to say apollo provider over here and just wrap it around with the highest level component and just wrap everything around with it like this and on the top over here we need to pass and specify a client because it takes a client as a prop and the client that we want to pass is this client that we created over here so i'm just going to paste it inside of here and now what should happen is we should establish a connection with our graphical api and our project is kind of ready to start making api requests to our graphql api so now that we have created this um let's actually start by um making our project be able to accept says such requests right so what we want is over here i just want to have a div right and i just want to say something like have an h1 which says list of users and i want to fetch the data and then just display the list of users below this so right now all we have is this thing saying list of users but it's totally fine um we'll i'll show you guys how to fetch the data now so what we want to do is we want to import some stuff from the apollo client library so the first thing i want to import is i want to import the use query hook now what is use query well the use query hook is extremely important for the apollo client library because it is the hook you use to make queries to your api similar to that there is a used mutation hook which allows you to make muta call mutations into your api um there's other hooks as well and you should definitely learn them i'm gonna show you guys one of them which is the used lazy query hook which is also very important but for now let's just focus on use query basically what use query does is it fetches some data from an api and it does it whenever the component renders so in our case whenever this component over here renders we should see the data being displayed immediately without us having to call any action or doing anything like that so to use the use query hook we'll just come down here at the bottom inside of our app component and actually what i want to do is i want to create another component um to fetch all the data so i'm just going to call this display data the reason why why i want to do it is because i don't want to like put everything into a single file and make it confusing so i'm actually going to just import the usquery over here at the top and i just want to um come over here and just render the display data component like this and you see it was automatically imported so it's totally fine in our display data over here i want to import from the apollo client library so from apollo client um i want to import the use query hook and inside of here i just want to say const const then i want to open and close and say use query and what we pass over here is the query that we want to make now what i want to tell you guys is it's a bit confusing um if you recall in the second episode of the series i showed you guys how to fetch data from the front end whenever you don't like you just have an api and you want to fetch data and throughout the series we've been using the um the apollo library which i'll just show you guys over here localhost 4000 which is actually oh i just realized our api is running on the local host four thousand so um i need to change this over here to be uh four thousand and not three thousand one i'm sorry about that so i'm just gonna say four thousand um throughout the series we've been querying data and fetching data using the sandbox right so to query data we just say something like this and it gets us all the data well it's basically what we need to do right now because we are now fetching the data from the front end so to do that we need to write some graphql similar to this over here to specify what we want to query now to do that we pat we create something called a gql statement so we need to import something called gql from here and to create a gql statement all we do is we come over here we say const then the name of our our statement which by standard it's usually something like query all users like this and by the way um i'm not really sure why we use all capital letters i've just always seen it like this and i'm not completely sure why this is a common a standard but um feel free to do something different i always do it like this so um i don't know why but yeah that's the thing you say you call it query all users you set it equal to gql and then you open and close backticks like this and you write gql code inside of here similar to what we've been doing in our type definitions over here as you can see so what we write over here is exactly what we wrote over here to query all users we just copy and paste it over here as you can see and we just specify okay i want to query i want literally to query all users so i need to specify which field from our root query we want to get in our case it is the users field because it is the the field that we want to query and we also specify um what fields inside of the user type we want to get so we can get an id an age a username and a name now it is very similar to what we've been doing so when you finish this over here and you create this query you basically just come over here you copy this paste it over here and it will make the request now how do we get the data how do we know if the data like if if it failed if there was any errors um that kind of stuff well the graphql the apollo client library allows you to get all of that information very easily by using the use query hook for example if i want to get the data i can just get the data out of it and this data variable over here should display the data so let's actually test it out let's say if data so if we have the data then i want to console log the data let's see if this will work now if i come over here and i just refresh my page let's open the console as well if i just refresh my page should we see the data and yeah we see the data so you see it console log the data it console log the the field users and each user is included over here which means that our api and our front end are correctly connected and we're able to see all the information that we are sending from our back-end so this is amazing it means everything is working and it means that we can continue just building more stuff so what else can we do with this use query hook well we can also get information for example if the data is loading so if the data is loading maybe we want to display something like this instead of returning the data down here we can return an h1 tag saying data is loading and you'll see that whenever i refresh the page for a split second it will say data is loading because it is while the data is loading while it's fetching the data it should display this information which is really cool and it's a really great addition from the apollo client library now in this case what you might want to use is like a loading spinner or a loading bar or some something like that but um for me i'll just leave it like this and it's totally fine we can also get any errors that might occur by just grabbing the error um variable over here and what you can do is you can do something like this you can say if ever then you may be just some error handling or just display something saying oh there some error occurred for me i'll just console.log the error just to see what happened um and i don't think any errors are happening so that's totally fine but the important thing is that we now have the data um available for us so how do we display this data it's a list of users so what we can do is inside of our return statement down here where we're just like returning ui stuff we can just come and say i want to if the data is available first because remember for a split second data might not be available because it's still fetching so we always need to ask if the data is available then i want to map through the data like this data.map and inside of this i just want to create a function which basically says that whenever for each element in data i want to return over here an h1 tag saying actually i'll return a a div just so we can actually display a lot of information so i'll say i want to return a div and this div will include the following it will include an h1 tag that says um name is equal to and then we need to grab each item so i'm going to say user over here and i want to say that the name is equal to user dot name because it is one of the fields that we're querying right we're grabbing the name regarding the age and the username then i want to do the exact same thing but for the age and the username which are the other two things that we want so i'll just grab over here the username user.username like this and we'll do the same thing for the age and say user.h and you should see that now it should be displaying but it isn't um it is saying that data.map is not a function which is kind of interesting and i know why this is happening but if you recall in our console log um i don't know if i deleted the console.log uh i did but basically in our console log over here um i'll just do it again like this if data is equal to data let's just console log data look at what happens um it will basically just con the data that we're receiving isn't just an array it's an object containing a field called user and then an array of the data so instead of saying that we want to map through data like this we want to say data.users or user let me see which one it is it's users dot map because we want to specify which field from the data has the data that we want so now it should be working you can see that it is actually console logging each user with its name its username and its age which is which is amazing right it's working perfectly now we can specify more fields if we want to um for example if you recall in our user type there is uh nationality so i can just come over here and say nationality like this and we can add a new field over here which for some reason should um show the nationality let's see if this works nationality and user.nationality and you should see that each user should contain a nationality below them which is really cool as well you can specify everything you get from the back-end right from the front-end which is the whole point of graphql right um so now that we know how to do this now that we're able to query our data let's add another one really quick um just so that we can use what we just practiced and be able to query movies try to do this without me showing um i'll just show right now but try to pause the video and try to on your own let's try to query um this uh field over here the where is it it's over here the movies field and let's see if it works so for us it's going to be very simple all we're going to do is we're going to come over here we're going to create a new gql statement let's say query all movies like this um and then instead of get all users let's just call this get all movies and we can just specify that we want to grab the movies um like field from the from our api and it will return a list of users of movies so each movie can have a name a near publication and an is in theaters um boolean so i'll just grab the name of the movie for simplicity reasons so i'll literally just grab the name over here and what we do now is we just create a new use query hook and instead of passing the query other users we we pass the query all movies now one thing you might wonder is okay but this variables all have the same name so what do i do now a very like common thing to do is just give them different names and to give different names all you have to do is you you see this data over here right this is a variable called data if i want to change it to movie data i can just put a column over here and change it to movie data and now the same data will be in this variable i'm gonna do the exact same thing for this over here movie loading actually i won't show any loading anywhere i just i just want to grab the data and for movie data i'll just come down here at the bottom below the data um that we're mapping over here and i'll do the exact same thing i'll just say movie data if it's true then i want to say movie data dot movies because we need to access the movies field from the query type and then i want to map through them and for each movie i want to just return a an h1 tag with a movie name so i'll just say name or movie name something like this movie name is equal to movie dot name and now you should see that at the bottom over here right below all the users we should get all the movies in our data set which is amazing it means everything is working now we've done a lot of stuff we've actually worked with just querying a list of of of stuff that we have in our api how do we actually just query stuff individually so we have these types over here for example where we pass an id and we can query a specific movie or a specific user but how do we specify and how do we actually query information uh based on an action right because right now we're just making a query and fetching data whenever we refresh our page or our component is rendered but how do we fetch data on command or on click well to do that i'm going to create a new component over here actually no i'll yeah no actually i'll just do it down here at the bottom i'll create a div over here and i'll just put an input and this input over here will be of type text like this and it will contain the movie name that we want to search for um so for example i can just go over here and say something like placeholder and i just want to specify something like interstellar just to give an example of how you write a movie name like this and then down here at the bottom let's just add a button which when you click on this button it's supposed to make a request and fetch the data from this movie that we wrote over here and i want to just display the data down here by creating a div and then we're going to display the data that we receive inside of here now how do we do this how do we fetch data on command well the first thing we need is the actual whatever the user wrote over here so how do we grab like values for inputs well it's very simple we need to basically just create a state so i'll create a state over here at the top and i'll create the state and call it movie searched or set movie searched something like this and this will be equal to the use state hook like this and we need to import it it was actually automatically imported so it's fine and this over here should be a string and it should start as an empty string now what we do is we just come over here to our input and we see that whenever there's any change to our input uh we want to detect that change grab the event and for each event for for each change we want to set the movie search to be equal to event.target.val and this will alter the value of the movie search state to be equal to whatever we wrote in this input over here which means that i can just write interstellar and now the state is like the value of the state is interstellar which is great because it's what we want to search for so now what we do is we come over here at the top and we want to import another hook from the apollo client library and this hook is called the use lazy query hook and lazy query just means that we want to hook for data uh like on command right we want to tell we only want to fetch the data whenever we tell it to fetch and it's very similar to the use query hook we just come here at the bottom we say something like const then we open and close um brackets instead of curly braces like this we set it equal to the use laser query hook and we do need to pass a query over here which i'll do in a second but what happens here is you can grab information uh from the from the query like this over here um but first you need to define the name of a function which we're going to use to call to fetch the data so for example if i want to fetch this data let's create a let's give a name for a function that would do that let's call it fetch movie and then over here we can do the same thing we did over here so we need to first pass the name of the function and then what we want to grab from the data so i can grab the data i can get any errors and those are the two that i really want to do for this one so i'll call this um i don't know movie search data and i'll call this movie error like this and this function will pass it down here at the bottom uh so that whenever we click on this um button so we'll pass a non-click we want to call the fetch movie function and it's that simple um you just basically specify a name of a function which you want to call to fetch this data and you can call this how many times you want and it will fetch the data every single time so this is basically it for the use laser query hook for setting it up now we need to write our query that it's going to be used to fetch the data so for getting a movie it's a bit different from this one's over here because if you recall we need to we need we need a variable right we have a variable over here um which is uh the movie name that we need to pass so we need to specify that whenever we write our query over here so i'm just going to say query and then i want to say get movie by name like this oh i completely forgot to to that this is not query this is const and i want to specify like this and set this equal to gql and let's open and close backticks and now what we want to do over here is we want to write a query similar to what we've been doing uh like over here where we specify a variable we give it its type and then over here we just use that variable and pass the value over here so to do that we'll just come over here and say we want a query and give it a name let's say get movie by name similar to what we wrote above but then we need to pass uh parentheses to say that we need to pass an argument or variables to this function so similar to this we declare a variable name by adding a like a money sign so i'll just say money sign let's call this name and give it a type so it's going to be of type string then over here we call the the type that we want to query which in our case it will be the movie type over here and when we require the movie type we specify that we want our name arguments or our name variable over here to be equal to whichever variable we pass to this query so we'll just say uh money sign name now i know i know 100 of this is confusing um and it is very confusing in the beginning but um just continue practicing on this just keep making more queries and working on more examples and it will make sense basically what we're doing is we need to first define a variable name over here give it as type and then when you query the field you pass the the variable that you defined over here to its value and the reason why we do this is because we need to pass this ver the value of this variable from outside of this query we we really want to do this right we want to set the name of the movie we're searching to this state over here so how can we do that if the query is predefined over here we couldn't just come over here and said something like the name should be interstellar we want to actually make this be dynamic and the name that is searched is the name that we want to search and that the user is actually trying to search so to do that we need to do it like this and we then just specify which fields from the movie type we want to get now we remember that the movie type includes um this field over here so i want to grab the name and the ear of publication for simplicity reasons so i'll just say name and year of publication like this now this is fine over here i think this this query should work let's just copy the get movie by name paste it into our use lazy query and now it knows exactly what it needs to or what it's supposed to fetch so what we want to do is we want to use this data variable over here down here at the bottom and like right over here and we would whenever we get the data so if data or actually it's not updated movie searched data so whenever movie search data is equal to true then we want to just display um an h1 tag actually let's just play a div like this and this div should include the data that we want and the data that we want is an h1 tag including the movie name and the movie name will be equal to movie search data dot movie because movie is the the field that we're querying dot name like this and we'll do the same thing for uh the other one which is the um the year publication so ear of publication like this and we'll say movie search data.movie dot ear of publication and now when we save this um it should not be working it is it is not displayed even if we click on this over here it will fail and the reason why i will fail is because we're actually not passing the variable so the movie name to the request that we're making over here now how do we do this how do we pass this movie search state over here as the variable for this so that it is actually querying the correct movie well there's two ways to do this you can either pass it over here by just saying i'm just opening an object and saying variables like this and just passing the data but i usually like to pass it through the function so there's this function over here called fetch movie and instead of just saying on click fetch movie we want to say that um on click we want to call the fetch movie function with the following arguments so i want to pass a variables uh property over here and for the variables we open and close curly braces to define that there is mult there might be multiple variables that are trying to pass to our query and we just specify which variables we want in our case we want a variable called name and the value of it will be movie searched the movie search state now we're actually fetching the correct movie depending on what we wrote on this input one thing that i just realized as well that i need to fix is um i mentioned this in the in the first second video when you have something like this over here where we're using variables like this the name actually matters uh if you're gonna give a name to this it needs to be either like empty or just the name of the field so in this case it's movie with a capital letter so something like this um and now what we can do is we can just come over here and try to test to see if it's working so let's just come down here and search for inter stellar like this and when we click fetch data you can see that it opens up a little bit more space because now it shows the data for the movie we searched now one thing that is important to understand is if i try to search for something that isn't a movie it will break you can see it doesn't show the data but we do want to see what the error was um obviously the error was caused because we try to search for a movie that doesn't exist so what we're going to do is we're going to check to see if this movie error variable over here exists and if it does i just want to console log it so let me say if movie error exists then i want to just console login and also um i'm going to select the movie like this and also maybe do some ui error handling like if this is not true like if this is true um we want to display this but if movie error is true then i want to display an h1 tag saying something like um there was an error fetching the data and when i saved this you can see that if i refresh my page and i try to search for something like interstellar we should see that it will work but if i try searching for something like um whatever this is it should say there was an error fetching the data and if we go to our console it should actually consolidate some sort of pretty fine graphql error which is this one over here it basically just says cannot return no for non-nullable fields so we tried to query a movie but it didn't actually return the movie that's what it's basically saying so now we have our beautiful app over here which i honestly looking right now it kind of seems confusing but we're able to query data from lists we're able to fetch data from a specific um like from one single user using variables when we're requiring data um and that's amazing [Music] we've dealt with a lot of stuff done a lot of things and um in the previous episode i showed you guys how to integrate react as the front end of over your app and how to make api queries to your graphql api so we are able to just query by using the use query hook over here as you can see and um just grab the data but we can also um fetch data um on on the basis of an event happening so we use the useless query to make that happen we have a function when we call the function with fetch data um so we focused mainly on fetching data and querying data but what we're going to be doing in this tutorial is going over mutations which um are extremely important because um they're the basis of of of a lot of of a big part of a graphql project if you recall if we go to our top definitions um we do have some mutations over here for example we're able to create a user we're able to update a user and we're also able to delete a user so what i want to do is i want to be able to call this mutation over here create a user and actually alter the data that we have and when we take a look over here and we create a user i want the user to also be listed down here as part of the data so how do we do that well the first thing we need to do is we need to come to wherever like we have our application which will be in the display data over here and um i want to clean up this a bit because um it's just like i i this was just for demonstrations in the previous episode but i'm going to delete all of this we're going to try to keep it simple and what i want to do is i want to create over here at the top uh a button which is going to be called create user and this will be used to create a user as you can imagine and i'm going to create a div to wrap around both this button and also all the different inputs that we need to create a user what do i mean by inputs well if we take a look at the create user type it takes it as an input on the create user input and the great user input takes in a name a username an age and a nationality so what we need to do is we need to take into account that to create a user we need to ask the frontend to send information containing a name a username and age and a nationality so for that reason we're going to come to our display data and we need to create some way so that the user who is like using the website um determines what is going to be the name what is going to be the the age the username and the nationality so how we're going to do that is through inputs and i'm going to create an input for the name all of them will be of type text i like this and i'll put the placeholder over here the placeholder will just say something like name and i'm going to copy this uh i think three more times right no it's age um username uh nationality um is it that let me see it's name username asia nationality so name username age and then nationality age will not be of type text because an age is a number it will be of type number and this will be username this will be age actually age yeah just age and then nationality so we have our four inputs over here which is amazing right you can see that if we refresh our page actually we didn't even need to refresh our page um they already appear over here at the top and how we actually make it so that whenever we write on these inputs we get the values as by doing the following well we've done this in the past with this state over here called movie search we need to create a state that is going to hold in the values for the inputs that we listed up here so how we do this is i'm going to copy this over here and i'm going to create down over here to make this seem organized i'm going to kind of put some comments over here so for this one i'm gonna put a comment um i don't know create user states and the first one that we need is is a name and a set name then we're gonna need um also an a a username an age and a nationality so let me just create two more um this is gonna be username and set username then this one over here is going to be age and h will be a number so its initial value will be 0 instead of a string and set age like this and then this will be nationality and set nationality so let me just put set nationality and what we do is we basically just copy the same logic we wrote down here at the bottom which is basically the logic for whenever something is written on the input if there's any change to the input we want to change the value of the state so that it represents the value in the input meaning that whenever someone writes on one of the inputs that we created it will update the state so that the value of the state is equal to whatever the input is so to do that we'll just change this to set name over here then this over here will be um set uh username then this one will be set in age like this and this one over here will be set nationality there is a caveat for the sat nationality which is if you recall our nationalities in our graphql is all um like in caps ladder as you can see over here so the way we're gonna fix this is by coming to our front end over here and when we have something like the nationality over here we want to um basically match the the format of this nationality uh like variable with um how we define it in our graphql server we can actually create an enum in the frontend if we want to that matches exactly how our graphql enum works over here however what i want to do is we just know that no matter what happens this just has to be uppercased so i'm just going to come over here and whatever they write it doesn't matter if they write it with uppercase letters or lowercase letters it's always going to um uppercase on it by default by using the function to uppercase so now when we when someone writes on this input over here uh whatever they write will be translated and set to the nationality state as all like in all capital letters so that's how we fix that issue now that we are actually saving all of the values of the input and we're actually we have our button over here what exactly do we do well we need to do something similar to a query which is we need to write some gql in the front end to make that call so what we want to do is i want to come over here and i want to create a create user mutation like this set it equal to gql and similar to what we've been doing i'm just gonna uh put the backticks over here and inside of here we wanna make a mutation call so how do we make a mutation call well we just say mutation over here then we give it a name and the name will be something like um create user then um we open and close parentheses and we open and close curly braces right now the important thing here is when you take it we need to take into account that we're gonna be passing an input over here now the thing we need to take into account is that um we need to pass some sort of input over here but differently from the kind of inputs that we passed over here it isn't actually just a variable that is a string we actually created an input that we pass as the argument of our mutation if you recall over here we created the create user input right so what we do in this case is we just come over here we create some sort of variable called um i don't know let's call it uh just input to keep it simple and set it equal to the same name that we passed um in the back end so that it recognizes the type and then instead of this we want to again say that the the mutation we want to call is the full is for the field called create user which is the field that we want inside of our mutation type and then we act we set the input which is the actual variable that this mutation takes in equal to um the variable that we pass as an argument to this mutation so we say input like this and then this over here should return a user right because that's what we determined and let's just grab the name of the user maybe the id as well um and let's test to see if this is working so we created this this mutation now how do we actually um use this inside of our react app well i'm going to come over here i'm just going to um call similar to the use query we're going to use another hook called the use mutation hook and this hook is extremely similar to the use query and to any other hook that we've used so far you pass over here a function that like it returns a function that you will be using so we can call this function create user and we can also grab the data and everything that it returns but for now let's just grab the function and we pass the mutation or the query that like the the gql statement they've created up here inside of this similar to the use query and they use lazy query and the thing is now that we we did this like this and what we do now is we just grab this function over here we go to our button which is this one over here and we just pass an on click to it like this and we call the function but since we're going to need to pass some variables to this function we need to create an anonymous function inside of here and then call the create user function that we grabbed from the mutation then inside of here we pass the variables and the structure of the variables for create user is as we did in the bracket right the first thing we need is an input so we say input like this and then for the input type all we have is um a name which will become the name variable that we created um and since we are actually in objects in javascript i think i mentioned this in the series um when you have two variables that are exactly the same name and you're there a key and a value in an object you don't really need to do it like this you can just write their name and it's fine now we're also going to pass the username the um the age and the nationality and this over here should technically work so now that we've called this function over here we have our button let's go to our server over here i'm going to just refresh the page because sometimes while we're writing it might give us errors and then i'm going to come over here let me just create a fake person let me call it paulo then the username will be i don't know i'm just going to write like random letters um and then what else an age will be 21 and the nationality let's make it something like um i don't know ukraine and when you click create user i want to be able to actually make the request so i'm going to open up the network tab over here and what should happen is a create user graphql request should appear as we click on the button so when we click on it you see it appears but it gave us some error um the first error it gives us is it says input cannot get invalid input at a value 21. so to this is it's kind of annoying but it's it's it's cool because it is good to show you guys how to debug right so let's for now um by default uh not pass the age uh let's make it so that the age will always be uh 21 so maybe i'm thinking that maybe the issue is with the um input over here and how it's being passed to our graphql server i think maybe this might be a string when it's supposed to be a number so let's try again uh let me try to submit it it doesn't matter what we write over here because now it will always be sending 21. when i click on create user it still gives us an error but it says that um the error is that it got an invalid value of ukraine um when it doesn't match uh the nationality uh like enum and the reason why it doesn't match the nationality now is because we didn't add ukraine over here so let's just do that real quick let's add ukraine save it and uh let's refresh our page let me try again with paulo um try everything again so you guys can understand how to debug this kind of errors right age again doesn't matter and let's try ukraine again so when i click create user you should see that it works it called a graphql endpoint over here a post request which um in our response it said that we just added them the user right and what happens is when i close this right now it doesn't show paolo over here because it just doesn't show we haven't refreshed our page but when we refresh our page it makes a request again and now paulo is over here and you can see the nationality is ukraine which is awesome because now it means that our we're actually making the mutation and it's actually working now obviously if you want to make it so that it will update automatically and you can just add stuff to the screen there's many ways we can fix this one way we can fix this is we can actually have um in our use queries when we make queries we can have something called a refetch so for example over here we have query all users right and query oral users is really cool because it will query our list of users but the problem is when we add a new user it won't add to the list and what we might want to do is we might want to tell our use query hook to re-fetch the data and query more users when we add a new user to the list so with this we can grab a function from a public client called refetch and now if i come down here at the bottom uh actually no it's uh yeah it's down here at the bottom in the button after we call the create user what we can do is we can just tell our thing our use query to re-fetch more data and when it refreshes the data it should add the user automatically to our list so let's let's make this work i'm going to add someone else so let's try putting someone called i don't know felix um then i don't know felix123 it's hard to come up with names uh the age again will be 21 and um i'm gonna fix the issue with the age in a bit but right now it's defaulting to 21 and then nationality let's just put brazil like this and let's hope it works so right now there's no felix down here at the bottom the last one is paolo and then we have a list of names of movie names because we also did that but when i click on create user we should see that it refreshed the data and now we have felix down here at the bottom we can keep adding people and it should keep going i can add felix's or whatever just another user a different age make it from canada and we click create user the new user should be down here at the bottom and this is good because it is refreshing the data it's getting more data it is updating everything on our screen based on the new data in our graphql api okay so um as i told you guys my guess was that um it was the number like right because this over here for some reason the input is being recognized as a text i always get confused by that um and it should be a number so right now what we're getting is we're setting age to be equal to for example the number 34 instead of being the actual like an actual number 34. so we just have to get this 34 which is currently a string and convert it into a number by passing the number function like this and we'll do this right when we pass h so like down here at the bottom um instead of just passing age we say age is equal to age but we're going to convert it into a number like this and if we save now we come over here we refresh our page we try to create someone uh let's call this person fraser i'm just reading random names around my room then fraser 456 the age will be 56 and the nationality will be let's take a look at a nationality that we defined um india let's say fraser's from india and we create user you should see that down at the bottom we have over here fraser the the age is perfectly fine and fraser is from india and it's working perfectly now we're able to add users which is honestly amazing it means that our mutations are working and this is basically it for mutations we are in the front end i definitely recommend using the refetch a lot instead of optimistic um like rendering instead of optimistically changing your your states and what i mean by that is the refetch over here when you add something to um to the array you just refresh the data right you add something to the to the database and you want to see it being displayed in your screen just re-fetch it to see the new values instead of actually directly altering the state because if i just came over here and i added to our um to this uh data over here the the not the movie data what is the name of the data um i think it's just data right this over here if i just added the new user to this array over here it wouldn't be correct because maybe there was some there that maybe some error occurred on the way so we only are sure that the data is correct if we're re-fetching the data and getting the data from our api so i would recommend using this a lot and we're going to go over a lot of stuff as well i'm thinking maybe we need we have two one or two more episodes left and if you're watching all of this throughout just a single video which i'm going to post at the end of the series um it's just a little bit more one more hour to this course because honestly when you get to this point uh i feel like it is a lot better to do it on your own um i gave you i'm giving you guys a lot of the basics a lot of the the syntax a lot of the like organization purpose actually i didn't talk a lot about organization my code is kind of unorganized for now but i'll go over that at the end of the series um but i'm basically just going over a lot of the basic stuff and you guys can use what you learned to do stuff on your own for example if you want to create a delete mutation just copy this and post it again and then change the mutation up here to be like to represent the delete mutation that we created in our schema right the delete user so you can try that out on your own and i think that it will be a great practice for working with this project [Music] i would like to welcome you guys to probably the last episode of the series where i teach you guys graphql from the beginning and the reason why i want to end this series um is because i tried brainstorming a lot of different topics that i would add and demonstrate throughout the next episodes however every single topic that i ran into was either too complicated in the sense that if i put it in a beginner series it wouldn't make sense it would it would make a lot more sense for me to put it into a intermediate graphql or advanced graphql series that i might make in the future or the topics weren't um valuable enough or weren't like it didn't have a a very common use case so it would make sense again to um edit to this series where i honestly am trying to get you guys to focus on the most important stuff and and just trying to make you guys feel comfortable with revql um so i decided that this is the last um three topics that i want to talk that i want to go over and i will go over them in this video so right now we're going to go over three different things we're going to first go over um what like the different arguments that you can use um in a resolver function so the different inputs that a resolver function might get we've talked about the args input but there's three more that i haven't went over and i think are important to at least understand i also want to talk a little bit about fragments and a little bit about error handling and how to use unions to like different methods of making cleaner code in graphql and how to error handle in a way that is acceptable in the industry so with that in mind let's get into the video okay so as you can see over here we have this um query which we've been um working throughout our series you can see that in our um i'm actually i'm gonna zoom in so you guys can see it a lot better uh but in our type definition for query we have a query for all users and a query for all the movies and what i'm doing right now is i'm just making a simple query and i'm accessing and asking for both the list of users and the list of movies which is something that i can do at the same time and you should see that um the result when i um run this is um a list um with users and also a list with movies this is something that i didn't show um in the previous videos but you can do it as well but the reason why i'm using this is because i want to show you guys an example of the different things that we can write in our resolver inputs so if you recall each resolver is a function as you can see over here and um we've been previously whenever we want to um ask for the client or whoever is making the request to send some data um for example if you're creating a user you want the client to send the data for the user right or if you're requesting information about a user you want the client to send an id so to access that information we can access the second argument in this function called args and i've previously told you guys that to access the second one there's the first one which is called parent but it really didn't go over and we really didn't use it so i will talk about that one right now and one important thing is it's not only parent and rx there's actually four so the third one that you might want to access is called context like this and the fourth one is called info and all of them have a different purpose some are more useful than others but the important thing to understand is that even though some of them like info is rarely used especially in the beginning you need to understand its use cases so that if you find yourself in a situation where you might need to use it or might need to access the information about the request you might use this kind of different aspects of our of graphql so the first one that i want to go over is parent so what exactly is parent so when you access the parent input in a resolver function it will basically return um whatever was returned from the the previous level in the graphql graph so i know that sounds weird but if we really think about it let me make a comment over here just to show you guys something um so we have this um graph over here right this is just a comment um we have over here the highest level which is the query right and below this level inside of the query we have um let me go to my type definitions we have users we have movies right and we have all this stuff as well but let's focus on the users and movies so for the users um let me just put an arrow over here we have users which is a level below the query level and if we go to the type of user um which is what it returns um there's actually another level because not only does user return users but it also returns a movie for the favorite movies and that's why we do have um a resolver individually for user where we say what favorite movie is right so we need we have this resolver i explained this um i think it was in the fourth or fifth episode but we have three levels and our users query so we have favorite movies over here now what happens is when we make a query um the parent over here uh will be undefined because query doesn't like this level doesn't return anything but when we query users um this over here will return whatever we want so for example over here when we're calling users right so in our case it is returning a list of ids and names so which is it's a list with a bunch of objects for each user which includes the id and name so the value that users the level of users is returning is this list of user ids and user names now then we have this over here which returns um a list of the favorite movies right this is what we we made it happen over here um so the problem is over here the parent will be undefined because query doesn't return anything but in the favorite movies resolver the parent will be whatever users returned so we're just accessing what the previous level returned now if we had another level over here another level um so another level would mean for example inside of movie there's um some field that returns another type so that if we had that um then basically we would have to um the the the another level will have a parent equal to whatever favorite movies return now i know it sounds confusing but let me just show you so if we have this users over here and i access the parent which is the first argument in the or the first input in the function resolver function and i console log this um let's see what happened um i will open my console log over here my terminal you should see everything is working perfectly if i run this query it should execute the um the user's resolver because we are querying for users and that means that it is console log in the parent and you can see it is undefined now if i didn't do it in the user's level and i did it in the level below it which is um the favorite movies um resolver and i access the parent you should see that if i console log this um like this parents you should see that um if i open my my terminal over here and i run it again what it should console log is all of this over here because it is the return value of the previous level and you should see that um did it work um did we actually save it oh we did like it's working perfectly but i forgot something um this won't be executed unless we actually specify and the user's query that we actually want the favorite movies field so let's just say that we want the favorite movies field we want to see its id and its name so the idea and the name for each movie that is a favorite movie for this user so now if we open up a terminal you should see there is nothing but if we execute the query you should see that um it returns perfectly it returns the information about the user that um was console logged now one thing that you might have realized is that well it isn't exactly what we returned and the reason for that is because over here we're returning the id and the name those are the only fields that we asked from the users but when we access the parents it returns much more than that it returns every single field that a user can have so this is an important aspect of it and it includes friends it includes nationalities includes age which we didn't specify in our request and this can be used for many things the use cases in our case aren't very valid but you should see yourself using this um a couple of times especially in a large project so i think it's important for you to understand at least why it's useful and how it works so now that we went over the parent argument we've went over args we've used it so many times let's go over context so what exactly is context in graphql well context in my opinion is the second more most useful input that you can have in a in a graphql resolver and the reason for that is because context is useful for many situations including authentication authorization also if you're using some sort of library that or some sort of api that will communicate with your resolvers and you need to have that quick access to different variables and functions and classes inside of the resolvers and you'll understand why basically context allows you to pass variables um numbers whatever values throughout every single resolver so if we have a value or variable that is useful throughout every single resolver for example some sort of authentication method or some sort of token we can pass it through the context and every different um resolver function will have access to that value by accessing the context let me give you an example uh to create and pass information through the context variable we need to come to our index.js and where we declare our instance of our apollo server over here we need to add a context property over here and context is a function like this that returns an object so in our case i'm going to open this up a bit so you guys can see it better at the end we need to return an object and and it can be whatever we want just as an example let's imagine that we want to have access to an object with a property called our key called name with a value called pedro so we have a user who has been logged in throughout the application and their name is pedro right and we won't have access to that name throughout every resolver we can pass this as a return statement for our context and if we come to any different resolver for example let's do it for the user's resolver and we come over here and we write all the previous inputs until we get to context and we console log the context let's see what is console logged so console.context let's open the our terminal up you should see nothing is console log but when i execute a query that queries users it should console log whatever we returned in our context object over here so you can already start seeing why this might be something important because we can use this for many situations including and most importantly authorization and authentication another example of why this might be useful is imagine if you're using an arm for a database system right so many people use mongodb so if you have a mongodb model that you want to have access in every resolver you can pass them over here like a user model and i don't know just access it throughout the resolvers without having to import them in every single file you just you just access them in the context right and that's that's cool that that prevents um unorganized code and it's useful in various different situations now one thing that i wanted to point out is a lot of people get confused in regards to um like things that are can be done in in normal express in normal rest apis and how to do them in graphql one of the things is accessing the request information like the the wreck object that every request has in in express so you can actually do this with graphql by passing this rec variable um inside of the context so to access a request of object um for every for every request you can just pass it as the argument to the the context function by grabbing it like over here and you can pass it inside of here you can say rec and you're returning the request now if i come to my resolver and i console out my context again like i've been doing you should see that when i run this it should console log information about the request and it includes everything right includes um the the graphql uh like query what we wrote the type of method the status code um if it worked if it didn't work um even like the the information about the computer you're using right so it's it's really interesting because a lot of people are confused by this and this is how you can do something like that um this would be very useful for example if we were passing headers um to our graphql api for some sort of authentication authorization method if we said context.rec dot headers for example in our case we're not passing any headers in the front end but this is how we would access because if i execute this query it should say the headers for the request which in our case is this but we didn't pass anything like specific and we didn't pass any tokens anything like that but i just wanted to show you guys um exactly how you would do something like that now this is context and it's really useful it's more useful than parent in my opinion and um than info which is the next one we're gonna look at uh so keep in mind and understand it fully you can play around with it and and do different examples just so you can get a better grasp of exactly what you can do with it now let's talk about the less input you can grab from a resolver function in graphql and i won't spend a lot of time on this one because to be honest i i don't think i've ever used it in a in a actual situation um this argument is the info input that you can get um and i'll just console log it so you guys can see what it is um if we console log the info um and we execute the query uh you should see that this is what it console logged it's just some information about the graphql request um it's not exactly like a wreck like we just console logged because it doesn't include a bunch of um methods and and stuff related to the request individually it is very like um funneled towards um the graphql aspect of the request so for example uh it gives you the field name which is users it gives you like what exactly it is it is a query it kind of gives you the schema as well some validation errors if you had any um any extensions any descriptions you put it it specifies exactly how the type is so specifies everything from our schema over here and it is interesting to just to take a look at it i don't find many use cases for it in the beginner level especially it is very it's it's somewhat useful and when you're doing some more advanced stuff um but for now let's just keep it like this um you won't be using this a lot i just had to go over it because um i didn't want you guys to not at least like have an idea of what it is so this was info and this were the four different inputs you can grab in a resolver function feel free to use them whenever you want they are important and they will be useful in different use cases so just knowing how they work and what they're used for is important so that if you find yourself you know wanting to use one of them to solve some sort of problem you can at least know um that they are part of the the the problem solving the solution right so now that we went over this let's go over um another important topic fql that i wanted to talk today which is um fragments so what exactly is a fragment right um it's it's kind of weird to explain and the use cases might not be as useful in the beginning but i would say that fragments are mostly used for um like organization purposes for uh maybe reusing code um in the client so that you don't don't have to keep copy and pasting the same code a thousand times right and what happens is in the client you can actually impose limits to fields that you're acquiring um in a query so what do i mean by that is imagine that we want to query our list of users right i want to delete this over here and i want to query our list of users but imagine all i want to see from these users for some reason i'm in a page of my website where all i need to see is the name and the age right um i need to specify that and whenever i use this query again i don't want to have to put down this fields again now it's only two fields but imagine that users may have a lot of different fields like many websites have some some important type like users include a lot of stuff because a user in a website can include many different fields and you don't want to keep having to write all the fields again what you can do is you can kind of specify um what this fields are inside of a fragment and it's almost like the knowledge i like to make is almost like setting the fields equal to some sort of variable and reusing the variable so that you don't have to list out the fields that you want from this type ever again and it also imposes a limit because you can't add stuff to the fragment after it's it's created you can query other fields on top of the the fragment but but that doesn't matter that much in our case um let's just get into how do we create the fragment so what we do is we just write inside of our client not in the back end we specify i want to get a fragment i want to give it a name so let's call it um get age and name it's a horrible name for a fragment but let's just call it like that and we need to specify which like type is this fragment going to be based on so this fragment will represent fields from the type user so we can say this we open and close curly braces and then we specify which fields we want to get to query from user which in our case is name and um age right so let's just put both of them over here and what we need to do now is when we make some sort of query that uses this fields this specific fields what we can do is we can just say dot dot dot and then specify the name of the fragment which is get agent name and you should see that when i run this it will query only the age and the name and if i add more to this like the nationality it will automatically understand and you will query all of this now again this is mainly used for reusability and it's really cool i like to honestly use it i use it sometimes for specific types like user because it usually includes a lot of stuff so feel free to use them how many how many times you want they are created in the front end so uh you got to keep that in mind and yeah that's that's basically what fragments are so it's a pretty small topic um now i want to really talk about um some more the type of advices that i would give um to someone working with graphql um on how to make their code look better for industry standards in the sense that like how do you error handle specifically how do you how would i error handle in in graphql it's something that i learned in a previous job that i had and i feel like it's very useful and it is one of the best ways to error handle because it provides you with a lot of insight on how to work with graphql and how to think of graphql as graphs which is one of the main points of graphql so what i'm talking about is error handling by using unions and result boxes and what i mean by result boxes is basically uh whenever we have a mutation or a query we we want for its return type for example let's go to our query over here this query over here returns a list of users right but the problem is what if there's an error and what if there's a specific error in our api or in our database that we're not seeing over here well graphql specifies primarily um areas related to graphql so like for example you put uh instead of an id when you make this query you put a string or or an or a boolean graphql will recognize that and will return an error but what if there's an error making a request to a database or there's an error making a request to an external api well graphql won't really give that much information about it so we need to do that ourselves but how would we error handle in this case well what i like to do and what i learned is one of the the good standards in the industry is you can basically create a union between um this return type which is what we want so the successful return type and the error now how would we create this union and how would we actually make it work so that um we are returning either one of those things right so basically what we want to say over here is for this user's type or this user's field we don't want to return this we actually want to return a union of two different things one thing will be our this result over here and the other thing will be some sort of error if it occurs right so what we do is we can create over here at the bottom a union and call it something like users result now to create a union you just write the union keyword and you write the name of the union then you set it equal to two different types in graphql now it must be types it can be scalars it can be arrays or whatever it needs to be a type so this is kind of a problem for us because um the successful return type for our user is an array of users right and the problem with that is that um we need to make another type which includes this as one of the fields so this is how we would go around this i would come over here and i would create a type over here called um users successful result um i know the name is horrible but just bear with me this is the type and inside of it it has um the type users and it returns uh this over here which is what we want to return from this so we put it inside of here and we see that this is a successful result from querying a list of users now this we can now be used as one of the options um in the union right it can either be this or some sort of error object some sort of error like that that is returned from our api now for that to happen we also need to create the error type so i'm to call this users error result and it's a type and inside of it we can put how many things we want but let me just put a message which represents the error message from this request right or from this query so the type of message will be stream and i'll make it required as well if it eventually happens so now we can say that this user's result is a union between the user's successful result and the user's error results so the way we make a unit in graphql is we keep separating the different results that we can have by putting this vertical line over here now we have these two types merged together that can can be both representing the result from a user's query so now instead of just coming over here and saying that users return users we're now error handling because we say that users can return users results which can either be an error or the array of users now how do we handle this because it is important to understand that we like right now we're not doing anything related to the user's error results it just exists but we're not actually like if there's any error what exactly do we do well the way we do this is by basically we're going to come to our resolvers over here and you recognize that we created a new type called user's result so what we have to do is we need to actually create a new resolver field for the user's result so i'm going to come here down at the bottom and let's just create a new um like on top of the mutations type and on top of the user's type there's another type which is on the highest level which is called the users results type so users result like this and this over here will include um in our case only one resolver and that resolver will resolve for both cases for the success and for the error so remember what we had over here this um this resolver over here for users it's kind of not as useful right now because um we don't have like the return type is not this it is actually um a union between two different things so we need to focus on this resolver down here at the bottom which will resolve and we'll check to see if there was any errors or if there wasn't any errors and the way we do this with unions is actually it's a bit different a resolver and for union uses something called a resolve type which is basically like a different type of function which you can use from apollo which allows you to specify what is being returned and like which of the two options from the union are actually being returned so from it we can access something called an object which will allow us to see the fields um that are returned from our um original uh like original resolver over here so what we're gonna check inside of this resolver is the following we're gonna check if um user list is equal it exists then we want to return the user list right so basically it's almost like if user list was like our database so we're querying from a database if there's no errors if it actually returns the list of users which is what we want then return this but if it doesn't um then it will come down here at the bottom and we'll get to a point where uh that this wasn't true so it should return an error so what we're going to return is an object containing um let's think about it it should contain a message and the message will be yo there was an error uh an error and by the way this over here is wrong right now because if you recall we changed the the type for our union our union doesn't return just a list of users it returns a type called the user successful result which is an object containing a user's field which then returns a list so instead of just returning users list we need to return an object containing a field called users which is equal to user list and if this is confusing which i know for a fact it might be um i would tell i just need to tell you guys to to relax um this is a complicated topic i definitely didn't get it first time i'm just pointing this out so that if you need to reference in the future watch it a couple times practice on your own so that you can actually understand everything and don't worry if it's if it seems confusing in the beginning but basically we're returning now either this which is the first option or the error which is the second option and we need to know if this if like which one of them were returned inside of our user's result resolver so the way we know which one was returned is over here we can come and say that uh basically if the object that is returned has a field called users then we know for a fact that um it is a a user right it it was correctly returned so like we were successful so we can just return the actual object.users that we received we're just saying okay if there if there was no errors return the whatever we received from our resolver above and if um the if it doesn't have that then we just know it was an error so what we want to return is we're going to return the object dot error so object dot um message right the object or message so uh these are the two things we want and the way we specified this and the way we tried this is let's open this up over here we have our api running let's try let's try querying for the users again i'll just specify that i want the id the name and the age right it's giving us some errors and the reason why it's given us some errors is because we changed the return value of users and this is something extremely important you can see that the return type for users now is user's results so how do we specify in the front end what we want from querying a union well the thing is when you query a union there's two different options right there's two different things that can happen a user successful result or a user's error result so what we do is we need to specify what we would want like each field that we would want depending on which case is returned so in the case that it returns a success we can put three dots and say um on user result not not user error but user successful result so if there's a success then we want to grab the id we're gonna grab the actually it's not then we want to grab the users field which is inside of this and the users we want to grab the id the name and the age i know this is confusing but basically what we're saying is if the result was successful then we want to query the users from the result and for each user we want to grab the id the age and the name now if it wasn't successful and if it is the case that it actually returns a user error result by the way it can only return one of those two types or else graphql will just give an error saying that it returned a wrong type right um and if this is the case then what we do is we basically say that we want to grab the message and this is it because message is a string is a scalar type it's not an object like users so we can just grab the message individually so now this is how we would form it and if we added more stuff to our union we could add more of this over here so when we run this example query you should see that it must resolve to an object it gives us an error and this is the message that we received now the reason why we received this message is because of the following i actually made a mistake here um the the return for when you're resolving a union is not exactly the result that you want to return back you need to specify which of the odd of the options um occurred right so for example we called in our union resolver over here um it can either be of type user success result or user's error results so what we return in our union is for example if the object.users exist then we know that it was the user successful result because users doesn't exist in the other type the other type only includes the the message field so we know it was an error if the message field exists so what we do is we actually return a string containing the name of the uh the union type that that occurred so in our case if it was successful the the option out of the union was the user successful result so that's what we return over here then we do the exact same thing but for the message so we just put if object.message um then we know it was an error and we just copy the user's error result over here and paste it down the bottom now what happens is um if none of those are true then it was a graphql validation error or any sort of graphql error that occurred so we can just return no in this case because it will know that it was a graphql layer instead of an error that we predetermined based on some sort of api call or some sort of database call something like that right so when we have this re done we can just come over here open this up open this up as well and try to run this and you should see that we get back our data we get back um data users a list of users perfectly because what we did is we said that um if the list of users exist then return a successful result right but if it doesn't then return an error so let's see the case in which it doesn't so the like the the analogy would make here is if there was an api error so we made an api request for the user list but we didn't get that data what would happen is the following i'm going to come over here to where we define our data which is um over here it's in the fake data.js and i'm just going to delete the this over here i'm actually going to set this equal to no like this just for a second so we can see what would happen so users list shouldn't be existing so when we run this query you should see that we get back an error type it says abstract type user's result and it gave us um an error message but it isn't the error message that we wanted um it says abstract type user result was resolve a type um users errors results oh okay i think i put it yeah i put an s at the end over here when it shouldn't be as you can see inside of our definitions it doesn't have an s at the end so when we run this again you should see that it recognizes there was an error that we determined um so it gives back a message saying yo there was an error but if we go back to our fake data and we put back um the data you should see that it actually returns the data instead of the customized error message that we created and yeah guys that's that's basically it um if you got to this point of the video uh i hope you watch the whole series um and i hope you gain as much value as you could again if you have any questions feel free to leave them down below especially in this video i'm gonna be answering all the questions you guys have um i was really really excited to make this series and it was one of the my best experiences because ravquel is one of the topics that i'm most interested in but i also find it one of the most difficult ones to actually get it um and especially in the beginning it is one of the cause of many many doubts and many many problems to beginners so i really wanted to make something that i feel i would have enjoyed if i was the one learning graphql right now so if you feel like you you gain any value from it i want to ask you guys to leave a like down below and comment what you want to see next subscribe and turn the notification bell as well to to see all the videos that i post i would be very happy if you could do so and yeah that's basically it um comment down below what you think about the series and i'm really happy that you ended up watching the whole video and yeah that's basically it really hope you guys enjoyed it and i see you guys next time [Music]
Info
Channel: PedroTech
Views: 74,090
Rating: undefined out of 5
Keywords: computer science, crud, css, databases, javascript, learn reactjs, mysql, nodejs, programming, react tutorial, reactjs, reactjs beginner, reactjs tutorial, typescript, react js crash course, react js, node js, express js, pedrotech, traversy media, traversymedia, clever programmer, tech with tim, freecodecamp, deved, pedro tech, graphql, graphql course, learn graphql, apollo client 3, usequery, usemutation, graphql tutorial, graphql fragments, graphql resolvers, graphql tutorial beginners
Id: yqWzCV0kU_c
Channel Id: undefined
Length: 235min 13sec (14113 seconds)
Published: Fri Oct 01 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.