GraphQL Crash Course - 2021

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody welcome back to the channel and welcome to a brand new crash course in this crash course we will learn about everything you need to know to get started with graphql and you absolutely need zero experience to start off with and by the end of it you will have a great depth of understanding of what graphql is and how to use graphql now as you know i like to teach things by building real applications so before we dive into what graphql is and actually coding graphql let's just quickly discuss the application that we are going to build so before we get to that i just want to show you a picture of my wonderful pet cat so this is felix and he is he's a sweetheart but sometimes he tells me that i'm a boring you know all i do is code all day and i don't give him as much attention so what he requested was well you know what i need to give him i need to give him a companion so i was like okay you know what i'm gonna get you another animal so you can hang out with now what do you do when you want things well you go on amazon of course so that's exactly what i did i went on amazon and then i searched for basically an animal that i thought would be best suited you know in this small studio with uh my pet felix so i was like okay maybe i can get like a baby rhino and i went ahead and i searched for rhino and i saw that there is no real rhinos around so i was like okay these are all toy rhinos but i want a real rhino and i couldn't find anything on amazon so what i decided to do was like okay maybe they're out of stock so i was like let me let me get another animal maybe you can get a tiger and similarly same exact thing i saw no tigers no real tigers per se i saw toys but you know this won't satisfy my wonderful my wonderful pet felix so i was like okay this is odd and then after a few more searches i noticed that well amazon actually doesn't do this two-day shipping with uh with real animals they can't just box them up and you know deliver them in two days and i thought you know what this is actually a need in the market we actually need this and you know when there is a need as a software developer and you know the person with an entrepreneurial spirit i actually went ahead and built out an application so i call this application animazon and so you can get basically all of the perks that you get from amazon you know two-day shipping prime but with real-life animals so essentially what we can do here is they have this application let's say you're interested in this chalamander well you can click on this challenger and you can basically add or buy them to the cart and essentially we would just put them in a box and we would ship them to you in two days this is the purpose of this application now the this application is a full stack application it is built with react and the front end and it is also built with graphql in the back end we will not be working much in the react side i actually built out this template uh out you know i built it out for you guys and essentially all we're going to be doing is we're going to be dealing with creating the backend graphql server in order to kind of transfer data between the front end and the back end so that is primarily what we are going to be doing but this is the application and again i always like to build real life usable applications and i think this would this would really suit well so again you can go over here we have this kind of cool header and we can also uh like search animals by categories so let's say we want mammals well we can see all the mammals that we need so we can do that and then we can also of course you know look for specific animals like so so this is the application that we are going to build and uh i will see you guys in the next section okay so before we get started i am going to mention my github page now if you want to follow along which i highly suggest and build out this application with me using graphql i highly suggest going to my github page at harblade7 and then at this specific repo graphql crash course at the time of recording it is private but it will be public once the video is published so over here you will see two directories we over here we have the final directory and this basically contains all of the code that essentially builds out this application so this is the final code once we are done with it includes the client which is the kind of the react side again we're not going to be dealing with the react side as much but mainly we're going to be dealing with the server which involves basically all of the graphql code now if you want to start off you're going to use the starts directory and if you actually open this up then all you actually see is the client and this is basically just contains this template over here and we are going to create the server from scratch so that's essentially what we are going to do and then we're going to have these two talk to each other so if you're interested in following along go ahead and either clone this repository or fork it onto your own so this is the repo right here and this is the url so i highly suggest to clone it if you want to follow along all right so let's discuss what is graphql now graphql is a query language and that's actually what the ql over here stands for so what is a query language well it is a way to communicate with our api and get some data we are querying for some data so essentially we use graphql to communicate between our client and our api and eventually our database to get some specific data for instance if we go to our wonderful amazon website let's say we want to render these three cards over here well as you can imagine in these cards there's pieces of information that we have to obtain from our server and our database such as the titles over here and the images so essentially what we would do is we would query for that data using graphql so we would have some sort of query and the query would ultimately look a little something like this so we would query for it our client will ask for that data and then our server will understand graphql and return back the data that we want so that right there is essentially what graphql's purpose is now you can imagine okay well i kind of know something that already does this a restful api i hit a particular endpoint and i receive data and it can render that data inside of our client now what is the point of graphql and to kind of illustrate this let's look at a few diagrams so over here we basically have a typical rest application so let's say we want to render all of these cards right over here so basically all of the animals inside of our application we want to fetch them so we can render these cards now as you can imagine there's specific pieces of information that we need to get such as the image we also need to get the titles uh the price you know the ratings and things of that nature for these particular animals now in a restful approach if we wanted to accomplish this we would hit a particular endpoint that we have created for instance over here i have my rest api slash animals so this is the end point and this will give us an array of objects and essentially it's going to contain all of the information associated with the animal entity so over here we have the title we have the id we have the price description the stock the type the rating the sale and the image and this is great now we can actually use this information to render this render these multiple cards however there's a little bit of a problem with this approach and the problem with this approach is we're getting back a bunch of data that we're ultimately not going to use granted yes we are going to use a title we will be using the price we will be using the image and the rating but everything else we're really not going to be using for instance we're not using the description in the cards over here there's nothing about a description similarly over here there's nothing about sales there's nothing about the type there's nothing about the stock so there's absolutely nothing that we need in regards to those columns there's only a few specific columns that we want now let's actually look at another example where we want to just query for one specific animal so for instance let's say a user decides to click on the line over here and he gets a bunch of this information so over here we have basically the um we have basically the description we have the stock we have the image so then to do this in a restful approach we actually have to hit another endpoint so this is going to be the slash animal endpoint and then we can basically put the id of that particular animal that we want to look for basically either as a query string or we can put it in the erectile body but then we face the exact same issue this time we're not getting an array this time we're only getting that one object but we're also getting all of the columns and we might not need some of these columns for instance we might not need the sales column so if you go back over here you know there's nothing really associated with sales in this particular uh page over here so we might not need this column whereas maybe the other ones we we do need so this is kind of a problem that we actually face constantly with a restful approach and this is actually known as over fetching this is over fetching our data now how can graphql solve this well with graphql we don't have multiple endpoints we only have one endpoint this is the only endpoint that we have right here just one endpoint and then from this endpoint we use the graphql query language to select whatever data that we want so again we don't hit specific endpoints we have one endpoint and then we use specific uh you know the graphql query language to hit whatever data that we want and this is basically what it would look like it would look something like this and if this doesn't seem familiar to you don't worry we're going to cover it in great detail in this crash course so we are basically going to query for whatever we need so over here we're saying okay well we want the animals and then from the animals i want the title the rating the image and the price because that is exactly what we need essentially for the cards that we want to display over here and as you can see that's exactly what we get we get an array of objects and essentially this array of objects only contains the title the price the rating and the image and so this is far better than this over here because we are com we are exactly fetching what we want we are not over fetching anything and as you can imagine with larger applications you know when our entities get very very large and complex and there's multiple columns it kind of gets overwhelming to continuously fetch for everything even though you might need a very limited amount for particular parts of your client application so this right here is what graphql is ultimately trying to solve another thing that graphql solves so graphql solves over fetching but it also solves under fetching let's say for instance over here let's look at our landing page as a whole let's look at this white part over here we have the categories section right over here and then we have the cards section so essentially to get the category we need to get all of the categories and we also need to get all of the cards of the animal cards now to do this in a restful approach we actually have to hit two different endpoints we have to hit the animals endpoint and then we also have to hit the categories end point so for any one particular endpoint we're actually under fetching all of the data that we need because if we only hit this end point well we're not getting any information about the categories and if you only hit this endpoint then we don't get any information about the animals so we actually have to hit two endpoints to get the data that we want well that is not a problem with graphql we can actually just make one call and we can say well i want the animals with these particular columns and then the categories entity with these particular columns and that way we can basically get all our data back essentially we're going to get an array of two objects one with animals and then one with categories and essentially we will be able to render this right over here and i actually kind of showcased this over here so this is the exact same query let's say we want to get the title and then over here similarly with the categories we want to get let's say the category itself so if we execute this you can see we get back an array of all the animals and then we get back an array of all the categories and this is great because well we only had to make one call and so this right here is is a lot better because with one particular call we are not under fetching all of the data that we need so this is a lot lot better and these are some of the perks of graphql over a restful approach and we're going to see much much more perks as we kind of continue with the crash course but these are the ones that i wanted to highlight so i hope that kind of enlightens you and gets you excited and i'll see you guys in the next section okay so in this section we are going to discuss some of the graphql terminologies that you probably won't see in a typical rest application so we are going to just quickly discuss these terminologies understand what they are understand what they do and then we will go ahead and actually create our graphql api in the next few sections so the two main terminologies that i want to discuss are the ones right over here schema and resolvers and so let's begin with schema so you can probably imagine what schema means in the graphql we have to identify exactly how our data is going to look so whatever entity we have in our application we have to describe all of the columns and the data types associated to that entity and we do this inside of well what is known as a schema and essentially for each entity inside of the schema we call that a type definition telling us this is the data that is associated with a particular entity in our application so for example let's say we had a person entity or you know people entity and essentially you know we had that inside of our application and we were using a graphql api well in our schema we would have this type definition right over here something that looks like this and it describes essentially the data associated to this entity so we say okay well we have type person and then we can say well there is an id over here is the column and then we specify the type the type of of that particular column now in graphql there is a special type for unique identifiers known as id and so we can say id but over here there's other things like name email over here the type is string so the type is string which is uh which is known throughout multiple programming languages and frameworks over here we have age which has a type of integer and then we have a phone which is a type of string and then we have gender which is a type of boolean say true is male false is female so this is what we actually have to do we have to describe our data in a graphql api and this is because well once we actually querying for our data graphql needs to know you know what you can actually query for and what you should expect to get out of it so if we write our type definitions and then we query for let's say a house address graphql is going to say hey no that's not in our schema it's not in our person type definition so that's something that you can query for similarly let's say you query for email and then you get a number back graphql is also going to say hey no you can't do that you're only going to get a string back so in graphql we have to define the type definitions of every single entity so essentially a schema is for us to define how our data will look now the data that we actually get back is dependent on the resolvers the resolvers are essentially functions so over here this is a resolver that return data that follow this schema now it doesn't necessarily have to follow the schema but if it doesn't follow the schema it is going to trigger an error if we try to query for something that isn't in this particular schema so well best practice is to have your resolvers follow the schema it's not even actually best practices pretty much required because you can't query for something that's outside of this schema but as you can see here over here we have a people resolver that returns an array of people and essentially you can see here we have an id of one which is a unique identifier and the id type over here we'll talk about that a little bit later we'll talk about the exclamation marks a little bit later as well but essentially the idea identifier ultimately translates to a string and then over here we have string string for name and email and then we have the age you have the phone number and then we have the gender so there we go these are the two main terminologies that we have to discuss before uh kind of diving deep into creating our api remember a schema is to define our data the resolvers is to actually send out the data that we ultimately want and the resolvers are going to basically be confined by the types in this schema so those are the two definitions i hope that makes sense let's actually go ahead and create our server so let's go ahead and build out our graphql api now before we do this let's go to the official graphql webpage at graphql.org and let's click on code once we click on code we can actually see all of the languages that graphql supports so we can essentially create a graphql api by using any one of these languages so we're not actually constricted to one particular language so for instance we can write a graphql api using javascript or particularly node and over here we can use go or php or python or java or ruby you know whatever you're comfortable with graphql probably supports it now in this case we are going to be primarily dealing with javascript so we're going to create a javascript api a javascript graphql api and then we're also going to be using javascript in the front end of course so let's actually go ahead and click on javascript and then it prompts us to a page with a bunch of different packages that we can use to actually build out our graphql server so as you can see here this is the server section to build out our graphql server we can just use graphql.js or we can use something called apollo server or we can use express graphql or graphql yoga or graphql helix now all of these might be a little bit different syntactically but they ultimately really do the same thing we're going to have a bunch of type definitions and schemas and a bunch of resolvers for instance over here you can just look at just the graphql.js over here we have a schema and over here we have a resolver right over here similarly with apollo server we have a schema we have a resolver the syntax is just a little bit different but really they kind of do the exact same thing over here similarly we have your schema and over here we have a resolver so really if you master one it's going to be really easy for you to master the other one so don't be discouraged for the one that i pick which is going to be apollo server because again if you master apollo server it's going to be really easy for you to master the other ones now why am i picking apollo server well it's because it is by far the most commonly used way of creating a graphql server and so that's essentially what i'm going to use and their syntax is great and very easy to understand so we are going to be using apollo server now we also have to talk about how we can actually query for specific data in the front end now to do this we have to essentially use another library for the client and there's a bunch of different libraries that we can use we can use you know graphql requests we can use apollo client or relay or amplify or whatever it is there's there's a bunch that we can use now specifically again because we used apollo for the server side we are going to use apollo client in the client side and again this is very very easy but if you know this you're gonna know the other ones so that is that's what i like about it and again the reason why i'm using apollo client is as you can see here it is very very popular by far one of the most start i guess relay is pretty popular too because this was built by facebook but you can see here i mean other than relay it's kind of miles ahead of all the other frameworks so we're going to be using apollo client in the front end to fetch data and our actual server is going to be used or is going to be created with apollo server so that is what i am going to do now if you are eventually going to build a graphql server with different languages so maybe like ruby well you would probably want to look at the different options so over here we have like graphql ruby and then we have aggo and then over here you know for rust we have other kind of options similarly over here for the clients and we can just kind of scroll through the different ones that you want or want to use but again for for this particular crash course we are mostly going to be dealing with javascript actually we're only going to be dealing with javascript and so we're only going to be looking at these particular frameworks particularly the apollo servers so now that that is understandable let's actually move on to the next section where we actually go ahead and code out our graphql apollo server okay so let's go on and build our apollo server now if you want to follow along again go to my github page at this url right over here our blade sevens dash graphql crash course and clone this repo and go into the start directory this is where we are going to be working with to create this wonderful application now the start directory contains only the client currently but we are going to add the server in this lecture actually so we're going to add the server directory right over here similarly if you also want to work you will need a text editor i am using vs code so if if that's the one that's actually most popular and kind of standard in the industry but you can go ahead and use whatever it is that you like again i prefer vs code if you like vs code go ahead and download it and lastly we are going to be dealing with javascript and particularly node in the back end so you need to have node installed so to install node just go just click on node go to the official node web page and just click on the recommended for most users and just go through the simple installation process now you can tell if you have node by going to any one of your terminals i'm going to use the integrated terminal in vs code and you can just do simply node version and right here is telling me okay i got version 14 and so i am all set now along with node you also get npm which is node package manager which allows us to essentially install a bunch of packages which we will especially for while installing the apollo server package so that is basically the requirements and now let's actually go ahead and create our apollo graphql server now to do this again let's go to the start directory and in here what we are going to do is we are going to create a brand new server directory and then in here we are going to create an index dot js so an index dot js so that is the first step the second step is to actually go to the start directory so i'm moving into the start directory and then i'm moving into the server inside of the start directory make sure you are moving into the server inside of the start directory and not the server inside of the final directory because again the final is done so make sure it's in the start and over here we basically have to do just a little bit of a kind of manual setup so over here we have to do npm init dash y and we're doing this basically just so we can get a package.json file inside of this directory which basically allows us to install packages in this directory as well so over here this is just a typical package.json we're also going to change the script over here to start and then for uh the script that we are going to run we're going to run nodemon index.js now if we want to run our application our index.js application typically we would do something like you know node index.js for instance let's do a quick console.log of hello and then if you want to basically run this file we would just inside of this directory you would just say node index.js and as you can see here we get hello however if i do end up changing this to let's say lower well you can see here that we have to actually re-run the server now this kind of gets annoying i don't want to re-run the server every single time so what we can do instead is install a package called nodemon so we can do something like npm install nodemon and then with the dash ge flag so we can install it globally inside of our machine so now essentially what we can do instead of something like node index.js we can do nodemon index and now if i go ahead and change this so let's go ahead and change this there we go you can see here it's kind of live updates which is great so over here in our package.json we're saying okay well we can do nodemon index.js so now because we specified that in our package.json we can use something like npm run start and there we go we get the same effect and that's why we are using nodemod all right so that is the kind of the initial setup let's actually go ahead and create our apollo server so to do this let's actually go to the official apollo documentation let me zoom in a little bit and let's go here with getting started with apollo so it says here the first thing that we have to do is well install these packages remember we have to install the apollo server package and then we also have to install the graphql package so let's actually go about installing these ones so let's go over here and let's do npm install apollo server and then also graphql which is a package that is needed well to create our graphql api so let's go ahead and install this and then over here it's saying create an index.js file we've already done this which is great and over here you can see a little bit of boilerplate so you can see here once the index is uh kind of done this is what we are going to need so over here we are defining some type definitions and then over here these are some of the data associated with our type definitions and then over here we have a resolver let's actually kind of copy and paste all of these and then we will discuss some kind of in detail and then we're going to refactor our whole application so we can actually build animazon which is basically what we want so the first thing that it's saying is we need to get basically this over here so we need to get apollo server and graphql from apollo server and we should be able to get this because well we installed apollo server to double check you can just do apollo let's see it should autofill apollo server and it does autofill and you can even do apollo server and then graphql over here you can see that now again i'll discuss these in a lot of detail so don't don't to worry but for now we're just going to do a little bit of copy and pasting so the next step over here we have our type definitions so over here we are creating our type definitions let's get rid of the let's get rid of these comments so over here we have some type definitions you can see here we have the book type definition that has a title and a string and an author that is a string and over here we have this weird type definition called query and it seems to be an array of books don't worry all too much about it we will discuss that in detail in the next sections but as you can see here this is basically what this graphql or gql tag is doing we use this to create our type definitions so basically we create our type definitions by specifying gql and then we use template literals and then inside of here we have our type definitions now for you if you copy and paste this and this is the first time that you use graphql this might not look all too nice for you syntactically now it looks nice for me syntactically because i actually have an extension a graphql extension so you can actually go ahead and install this extension right over here and this just allows us to have nice syntax highlighting so go ahead and do that so there we go so over here we have defined our type definition which is great so what is the next step well the next step we need some data that basically follows this type definition so we can say okay well here is this data this data at the moment is basically stored in our application as an array but this could come from a database and primarily it would come from a database but again it would probably it would have to follow this schema right over here with title that is a string an author that is also a string so there we go that is the first step so now we have our type definitions our schemas right over here we have our actual data that follows the schema and then the next step is we need to define our resolvers so let's actually go ahead and copy this again if i am going too fast this is just quick like little setup i'm going to go in great detail with every single thing yeah in great great detail so don't don't worry all too much so over here we have our resolver and essentially what this is doing is basically resolving resolving this books query so essentially here we're defining how our queries are going to look like because we actually have to define those queries and define what we are getting back so essentially this is what this type query is so we're saying is okay well we can actually ask for books and this is going to return an array of book and book basically is something that follows this structure over here so an array of objects where we have a title that is a string and then the author that is also a string so now we in our resolvers we are essentially resolving for this we're saying okay well in this basically query definition we have this thing called books and we are going to return over here this is a function books this books right over here so we're basically saying that we are going to return this array of objects that follows this type definition right over here okay so that is that step and then we need to create an instance of our apollo server so let's actually go ahead and just quickly copy this and then let's paste that in and so over here we are creating an instance of our apollo server and in here we are defining our type definitions so over here our type definitions and we're also defining our resolvers so over here we have all of our resolvers and then we are just doing a typical server.listen essentially just launching our application so there we go we have created our first graphql api so now what we can do is we can do something like uh mpm run start and there we go we are now listening on port 4 000 so if we go to 4 000 so we can go to localhost 4000 we get this kind of interface right over here and this might be a little bit strange for you this is known as the graphql playground so essentially we can use this to kind of query for data like we would query for data in the client again if this is kind of just boggling your mind what is going on here don't worry we're gonna go through everything in great great detail this is just a quick introduction quick boilerplate that we need to get done to kind of continue this crash course so now what we can do here is basically we can query for data and particularly well we only have books that we can really query for so over here we're saying that we can query for books so what we will do is we'll say well we want to query and then in an object we say all the things that we want to query for again we only have the options of books and as you can see here it's self-documenting so we can say books and then we can say the things that we want from books so we want the title and we also want the author and then there we go we get an array of books and that is basically our graphql server that's essentially what we're doing now if we don't want to uh if we don't want authors we can go ahead and just say title and there we go we have titles so we can specifically look for exactly what we want now let's say we just do books on its own well this fails because for something that is defined in our type definition we actually have to specify no matter what what it is that we want so we actually have to define that hey we want author and title and there we go so that is essentially our first craftql api so if you successfully got this to run there you go you created your first api congratulations now in the next section we're actually going to be modifying this api to create this kind of header right over here let's actually zoom out a little bit so we're going to start off a little bit easy so we're just going to essentially have our data in our api and we're gonna basically want to fetch it into this header so this is basically what we are going to do so we're going to basically do it we're going to basically be doing quite a bit of modification and talk about each step in a lot of detail so i'll see you then okay so now that we have built out our boilerplate for our graphql apollo server let's go ahead and modify it a little bit and kind of add our own types so over here what we're going to want to do is we're going to want to work on this section right over here just this hero section this right here will always keep the same but let's say we want to kind of dynamically add this data in and therefore we want to get that from our graphql api so essentially we have to create some sort of way to get data associated to these cards now what are the data associated with these cards well we have a title over here so we have a title and we also have an image and that pretty much seems like it's it so those are the three or sorry the two pieces of information that we need to get from our graphql api to render these cards now what we have to do now is actually define the type of data inside of our graphql api using the type definitions so this is the very first step is defining how the data is going to look like for this entity right over here so let's actually go about doing that so again inside of our type definitions we are going to add another type another entity that we are going to use to describe how the data is going to look so over here we can add another type and we're going to call this main card and then we're going to have curly braces and then in here we are going to define the columns and their associated data types so let's go ahead and do that so over here if you go back to our application remember we have a title that is going to be a string and we also have an image that is going to be a string as well some sort of url so let's go ahead over here and let's say title and then we're going to say well this is going to be a string and then we're going to say well we want an image similarly this is also going to be a string so right now what we did was we defined our type but really we're not doing anything with it now one thing that i want to note is once we def if we can define things other than string we can define things like let's say i don't know maybe if we need the age well this could be an integer so this is a number similarly we can also have something like float so this is a number with a decimal point whereas integer we don't have decimal points and then you can have something like let's just do a let's just do you know what let's just do here we'll remove this a little bit later this is a float this is a number and then we can also have other ones like let's say booleans so booleans either true or false so over here these make up scalar types so essentially a string a float an integer and a boolean is known as scalar types whereas when you're actually referring to another type for instance this main card can actually refer to another type and we'll get to that a little bit later just like really these books right here is referring to an array of this type this is not a scalar type this is actually referring to a interface itself so so right here we are defining scalar types just a little bit of terminology so let's actually get rid of these so right now again we are just defining how this data is going to look the next step is to actually define once we want to query our data how the data is going to look once we get it back well over here what we would do we would say something like main cards and then we would say okay well we expect to get back and array so an array not so not just one but multiple and that's because we have three over here we could have more multiple of this main card type so essentially here we're saying that okay if we query for main cards what we expect is an array of objects that contain title that is a string an image that is a string now if you go ahead and save this we can see here that it works perfectly fine so let's actually go about and query for this so now let's do a quick refresh of our server and then we want to say query and then go ahead and query now if we um now we can also leave off the query and then it will be an implied query but you know what let's actually add the query just for the sake of just for the sake of just clarity so now we can say main cards awesome and then within our main cards we can ask for what we want we can ask for the title and then we can also ask for the image now if we execute this we get null back and the reason for this is because we don't have a resolver that is returning any data that follows this kind of constriction right over here this data type so let's actually create that right now so let's kind of copy what the book have over here we're just going to say main cards so main cards this is basically the data now this data would ultimately come from our database a resolver will probably be making some sort of request to our database to get this data and then it would send it off but for the sake of simplicity we're just going to leave it over here as an array now let's go ahead and let's say that oops why is this four this is odd let's just say uh the title of this book is um let's say i'm trying to think of a quick book i don't even know who this author is i'm trying to click if i think a book um let me look at my book collection let's do let's do [Music] let's do blink let's go blink that's a good book all right so over here we have some books for i don't know why i spend so much time thinking about a book we're gonna delete that section anyways so let's say over here well okay so let's actually add our data in here so we got our recently reviewed and then let's say we have an image of a lion so this is let's say our url for this particular image and we have looking for a gift and then we have over here a an image of penguin and let's remove this from author to penguin and then lastly what we're going to do is we are going to let's just clean this up a little bit we're going to add the last one i believe the the image is a cat and the title is best behaved so now we can just add that in there awesome possum and so now in our resolver so we go into the query so essentially now what we want to do is we want to resolve basically this query right here how this is going to look like we want to resolve this query so we can go into basically the query section and then we can say well okay so main cards and then that is going to resolve to this data right over here so essentially what we're saying is okay this is how it should look like again the type definition is just describing how our data should look like so how the main card should look like how the type should look like and how our queries should look like so we should be able to query for books and get back an an array of basically objects that contain title and authors similarly here we should be able to query for main cards you know and get back an array of objects with title and image however this is just defining how it should look this is very very important this is just defining how our data should look the resolvers itself are the ones that kind of resolve what the actual data is going to be so over here we're saying that okay well we want to resolve this main cards over here this main card's query and we are going to return back we're going to return back this array of objects right over here let me actually zoom out a little bit might be a little bit easier to see so again we want to basically resolve the main cards and return back this array of objects and resolvers are functions because you know well we might be actually doing some complex logic in here such as you know asking for data from a database and things of that nature we might want to do validation and things of that nature so so that is basically that so now once we save this let's go ahead and go to graphql playground and now if i execute this exact same query there we go we get our data now if i revert to remove image there we go we get only titles and that is basically the power of graphql you can really fine-tune the things that you want you don't you're not kind of constricted to getting everything back even though you might not need these things so that's kind of the power of graphql and that's why it's it's something that i always use in all of my projects all right so that is pretty much it but one thing i want to discuss is let's say that for some reason you know our image is undefined one of the images is undefined and so it's it basically returns back a null now if we were to execute this you can see here that it is totally okay with that even though even though over here we have not defined anything about it being null right we're saying that okay the string can be or sorry the image can be a string the title can be a string it can't be a number so let's actually change this to a number let's see if that does anything so if we save this and we change this to a number i guess it returns the number of four let's see if we uh change it to a boolean it returns the boolean uh or sorry the the string of true so it basically converts things to strings however with null it's okay with it it just it just returns null even though right here we clearly defined that we want a string now by default what happens is is when we define our scalar types or where we define any type for that matter it could be either the thing that we've defined or it could be null so that's exactly what's happening here for instance if we define something like you know some sort of float we're saying that okay this could be a float or it could be null now if we want to basically specify that this absolutely cannot be null what we would do is we would add an explanation mark or a bang at the very end so we're saying here this absolutely cannot be null it has to be a string so now if we go back to over here we have null remember when we previously executed this query this was null now if we were to execute this again there we go it says cannot return null for non-nullable field so we get some sort of error so we would actually have to go ahead and change this to back to lion and then if we execute this again there we go awesome so that is that we have successfully done our first uh kind of you know uh our first custom query and i hope this really makes sense remember type definitions define how our data would look okay and this type query is very very special the keyword is very special because it's just defining how we can query our data so right over here that's type query and these are basically how our other data is going to look like this right here is just our data again this could come from a database you know our resolvers can have some sort of like complex logic in here maybe we can have something like if we're using like a mongodb database it could be like something like main cards you know we can use some of the models main cards.find you know we can have like a async and then over here like a weight blah blah i'll see here like let's say main card and then you know dot find whatever this we can we can say like oh we want to find them all and then we can just say um well we want to return the main card you know we can have some relatively complex logic and actually reaching out to the database instead and again in this crash course i don't want to deal with actually working with the database instead what we're going to do is just simply just have our things stored in an array of objects so over here we're resolving it and we're kind of resolving how our data is actually going to be so there we go we have resolvers we have data and we have type definitions and we've basically successfully uh created this part over here later on in like much later on in the crash course we're actually going to go into the client and actually fetch the data and it's going to be very similar to what we have over here but you know there's just a little bit of nuances so now in the next section what we're going to do is we're going to work on these cards over here and this should be relatively similar to what we've done so far and then later on we're going to work on the category section and this is where we're actually going to see some sort of relationships anyways let's go ahead and move on to the next section okay so let's move on and let's work on the cards section right over here now this contains a lot more data as you can imagine and thus it's gonna be a little bit more complicated but it's really going to follow the exact same steps so let's go about doing this right now so the first thing that we have to do is we have to define how this entity is going to look now each card is describing a particular animal so we're going to call our entity animal now before we do this let's actually go ahead and remove anything related to books in our application so let's remove the the books array let's remove the books query and let's also remove the you know the type definition in our books over here and then we can remove this just because we don't need it anymore and it just kind of adds a little bit more glow into our application so again what we want to do is we want to add the type definitions for these particular animals so let's go ahead over here and we can do this anywhere the order doesn't really matter and we can say animal and so now we have to define the types associated with an animal well over here we have some sort of an image for each one okay so we're gonna say well we need an image and we're gonna say that this image is a string and we're going to add a bank telling us that we absolutely need some sort of image and it cannot be nullable the reason for this is well because we can't really showcase a project or a or a product or an animal in this case if you don't have an image so there we go we're gonna say that this has to be provided as a string if we are going to provide it so that's the first thing over here we have some sort of uh some sort of title so let's go ahead over here and let's say title and then this is also going to be a string and we're going to say that this is non-nullable as well all right so let's move on over here we have some sort of rating now for the sake of this application just because it makes the front end a lot easier we're going to assume all of them are five star ratings so over here all number five start rating so we're not really going to be dealing with that type of data but let's actually add it in anyways let's actually add in rating and then this is going to be a float because it can either be something like 4.5 or 5.0 and things of that nature now typically this will be something that we absolutely need in our application you know for a real application like amazon they actually want to showcase a rating so this shouldn't be a nullable field however because our application all of our wonderful animals are five-star rated we're just gonna leave it without the bang all right so without that exclamation mark saying that hey this could be nullable but over here this is another scalar type that we can use all right so let's move on the price so the price itself could also be a float or some sort of numeric but what we're going to do is we're going to have it be a string just so we can add basically this wonderful comma wherever we want very very easily so we're going to say the price the e string and also typically once we're working with stripe actually the price is is kind of given to stripe as a string but that's just a another another topic for another day there we go we're gonna say that the price is a string and it should not be nullable that's why we added the bang at the very end over here we're gonna say uh over here we have some sort of like delivery date now this is not a big deal we're just gonna leave this whatever as as it is so we're not going to actually include this in our database but we could if we wanted to add some sort of string but we're not going to want i'm not going to do that just for the sake of simplicity so this is just going to be static no matter what it's going to be free delivery by tuesday february 16th now once we click on a particular animal let's say we click on the lion there's actually more data associated with it over here we have some sort of a description so over here we have a description um over here let's see i don't know if we have anything else it seems as though this is what we have so so over here we can say that we have a description so description we can say that this description is a string however if you look at it this description is kind of contains multiple points right over here so we have a point over here a point over here a point over here and a point over here so it seems like it is kind of an array of descriptions and so what we can do is we can define this by saying that well okay this is an array of strings now we can say that this is absolutely required by adding the exclamation mark so you know without the explanation mark it could be an array of strings or it could be a nullable value but by adding the bank at the very end we're saying that okay this absolutely has to be an array of strings and not nullable now inside of the array we could have strings or null values so over here we can say that okay if there's an element inside of this array this absolutely has to be a string and we can kind of specify that with another bank inside of this array so over here we're saying that over here we absolutely need an array of strings and then over here with this bang we're saying that okay inside of the array it cannot be nullable it has to be strength so there should be no value that is null there we go we have basically defined our animals the one thing that we are missing is um we're missing this over here which is the stock so we can say something like uh we can say something like let's do stock and this is going to be an int let's say this is also non-nullable and let's also add a boolean type so let's say something like on sale we're just going to say this is a boolean and this is not required okay we're just going to say this could be a nullable value if we wanted to so there we go we have defined our animal type so now okay what's the next step let's go ahead and save this nothing seems to break so now let's go ahead and let's actually add that basically type definition in our query so because right now if we actually go to our query and we go ahead and try to um try to query for some sort of animal so let's go you know animal we actually don't see it we can actually look at the docs right here we can see here that we can only query for main cards and that's because we haven't described how our query type definitions are going to look like so now we can say something like okay well we can query for animals and that should return an array of the type animal so again should return an array of objects with these particular types and so if we go ahead and we save this now if we refresh and we look at our documentation we can see here that we can actually query for animals as well so now we can say we can query for animals and then you know we can get their description we can get their price however once we execute this you can see here we get null now the reason for this is because well we don't have any value associated with this now we can also kind of trigger the error by saying you know exclamation mark exclamation mark so that's that's basically saying that hey you know we shouldn't get null so we can basically trigger some sort of error now if we execute this we can see cannot read null for non-nullable values all right so let's actually go about creating the basically the data associated with our uh our query now one thing that's happening here is this kind of is getting a little bit messy so let's actually move our data into a separate file so let's go ahead and inside of our server in the start directory let's create a db.js file and essentially all we're going to do is we are going to just cut our data we're just going to paste it in there and then we are going to do something over here we're going to do const animals and then we're going to say we're going to say let's copy paste basically this right over here because this is exactly how it's going to look like so we're just going to copy that and let's just say image lion and then let's just copy this later on i'll i guess this is a little bit more difficult let's just just add dummy ones later on i'm just going to copy and paste the exact data from um from our github page so let's go here let's just add just some something dummy right over here this is an array of strings let's add a comma this is some number and this is true cool so now what we're going to do is we're just simply going to do a module module dot exports and we're going to export these data types right over here so we're going to uh export these stones right here and so once we save this we can actually import this into our applications we can say something like well or sorry we do something like const and we can import from our database file you can get the main cards and we also can get the animals and there we go basically now we have a separate file to define our data there we go so now essentially everything should be working as as working perfectly once we save this because now we still have our main cards now in our resolvers we can say that okay to resolve this particular uh to resolve this particular query where is it this particular query we can say that you know animals essentially you know this is the function and it returns animals and remember animals is coming from our database so if we go ahead and save this everything still works perfectly fine and then what we can do now is we can go ahead and we can actually query for animals at this point so now if i were to execute this exact same command you can see here that i get this data so that is pretty awesome and we can actually you know really selectively ask for what we want so we can ask for stock title whatever it is that we want and there we go so that is awesome like this is this is really awesome this allows us to basically get all of the data associated with um with you know all the animal data in our application so we can render these basically cards over here however there's a little bit of a problem what if somebody clicks on a particular card so they click on this card and now we don't want to render all of the data associated with all animals we just want to render the data associated with this one particular animal so how do we go about doing that that gets a little tricky so we're gonna actually look into that in the next section okay so the next step is to create some sort of resolver that only returns one animal so right now we have a resolver that returns all the animals in our database so basically it's going to contain um over here we have so the next step is to create a resolver that only returns a one particular animal based on some sort of unique identifier so that when we click on an animal we only get the data associated with that particular animal right now we have a resolver that returns all of the animals in our database remember this is all of the animals currently there's only one object but let's actually quickly fix that at the moment let's go ahead oops let's go ahead and let's move back over here let's go ahead and go to my github page and then go to again this particular url or if you cloned it all you have to do is go to the final directory the server directory and then the db dot js and over here you can see that we have the animals let me quickly zoom in so we have the animals array with just a bunch more data so go all the way down until we find the closing bracket of this array and just copy everything right in and right in and just copy that instead of this right over here so now if we go ahead and save this now we are returning every single kind of element inside of our array because this is exactly what this resolver is doing is we're turning every object every single animal inside of our database and this is going to be our database for just the time being so now if we go ahead and query for this you can see here we get a bunch of data let's get rid of the description because that's just a little bit bulky let's just do something like i don't know the title and then we can see here that we get every single animal inside of our database so this is not what we want when someone clicks on a particular card we actually only want to return this object right over here so we probably just want to return the first one right here so how do we go about doing that well we're going to have to create another resolver and this resolver is only going to con only going to return just one animal so let's go ahead and let's think about how we are going to do this well the first thing that we are going to do is we're probably going to have to you know search through and iterate through this existing array this existing array and find that okay this is the object that we need to return now how do we go about doing this well we're going to go about doing this by having some sort of unique identifier within each object now this unique identifier could be an id or it could be something like a slug a slug is basically the slash over here that we kind of append at the very end of our um of our url and this basically identifies let me just i guess i can't zoom in but this basically identifies that okay this is slash line this is referring to one particular product now this is going to be a unique identifier and it should be unique across all of the products all of the animals inside of our application and that's exactly what we're gonna do we're gonna have basically a slug that is unique based on essentially whatever the animal is so once we go to a particular animal in our react application we are going to get this slug and then we are going to query for the correct data based on this slug so let's actually go about doing that right now in the uh in the back end now also we should always have some sort of unique identifier even though we might not use it eventually maybe later on we're going to use this we should always have some sort of unique identifier and therefore we should actually change that in our schema so let's go ahead and let's add a slug type and an id type so let's go ahead and let's go to our index.js in our server and let's go here let's make a few modifications we're going to have an id and this is going to be of type id now this ultimately is going to translate to a string but this is just telling graphql that this is a unique identifier similarly we're also going to have a slug and the slug is going to be a type of string and this is going to be you know has to be a string it can't be a non-nullable value so now if we go ahead and save this we can actually go ahead and query for well slug and we should be able to get our slugs over here you can see a slug of lions log of chameleon so if we decide to click on like the dolphin we should see slash product slash dolphin that's essentially what this slug is saying all right so now what we can do is you know if we decide to go on like slash lion we can extract this slug and basically find the correct object based on whatever this log is so we can basically find this object now remember look all the slugs are unique so let's go ahead and let's figure out how we can do this now to do this we need a new way of querying our data so let's go to our query and we're going to say that okay well we want to query not for animals this time we want to query for an anomale so just one animal without the s at the very end and this is going to just return one particular animal and it's always going to return one particular animal actually you know what we're gonna say that uh um we're gonna be like okay you know if you provide us with an invalid slug we could possibly return null so we're gonna actually make this non bankable so this is not this could be null as well so basically essentially what we have to do is we have to somehow provide that slog to this query now to do this all we have to do is add parentheses right in front or right after the animal and then in these parentheses these are basically the arguments that we are can define with this query so we can say something like slug and this is going to be some sort of string and this is going to be required if you want to query for an animal you have to provide us with some sort of slug so now if we go ahead and we save this we can actually go to our our playground and we can see we can actually query for an animal so we can actually query for an animal and then we can ask for whatever it is that we want let's say we want the title okay but then we also have to provide a slug right over here so we can say something like lion now right now we don't have a resolver and that's why we are returning null so let's actually go ahead and create the resolver that resolves the data for this particular query right over here so now all we have to do is just create a animal resolver and something that i haven't mentioned yet is that the parentheses the function over here actually takes a few arguments so so there's there's three main arguments there is the parent argument there is the args argument and there is the context argument now we're going to talk about all three in great detail but for now we're going to focus on the middle one so let's go ahead and let's execute this and let's just console.log the arcs that's that's all we're going to do at this point so once we execute animal so once we basically execute this query this resolver is going to run let me quickly just zoom in so this resolver right here is going to run so again once we execute this right over here the animal query this resolver is going to run and it's going to console.log the arcs so we should be able to see it right over here inside of our terminal so let's execute this again we get null and there we go we actually see the args and there we go the args is a slug that is lion so we can actually use this to our advantage now what we could do is we could do something like this we can do something like okay well let animal the animal that we want to return and then we can basically iterate through the animals array so remember this animals array you can iterate through that with the find method and essentially what the find method does is it finds the first thing that follows a kind of a specification that we set so we can say for each animal we're going to say okay if the animal dot slug is equal to the args dot slug and so essentially this right here is going to find so essentially what the find method is going to do is it's going to iterate through every single it's going to iterate through every single object in our array in our animals array and what it's going to do is it's going to compare the the item that we're currently iterating over its slug value to the slug value inside of the arguments that we have over here so it's slug value of the item that we're currently iterating over and then uh this log value of um of the argument so for instance let's say that uh let me just quickly walk you through this because maybe you guys don't come with from a javascript background but this is just literally a loop in in in kind of just the simplest case it's really just a loop that we're doing so let's just say i want to find chameleon so let's go over here and let's say chameleon and so what we would do here is we would iterate through the animals array and so we would first begin with this right over here and we would say okay well is its slug value which is lion equal to the one that is equal to the rx dot slug and remember the arx of slug is whatever that we pass in over here so this is going to be an object of slug.chameleon and so in this case though it's not so it's going to move on to the next one so it's going to move on to the next one and in this case well its slug value is equal to the args dot slug because we change this to chameleon and so now what it's going to do is it's going to return that a particular object into this variable over here and now all we have to do is simply just return that animal and there we go so we can just return that animal and now what we can do is if we actually go ahead and execute this we get cannot access animal before initialization i wonder why that is let's see okay let's that's because this is called animal it's just a bunch of things that are called animals this should also be called animals so let's let's fix that and then let's execute this and then we get null for some reason which is quite odd i wasn't expecting that actually let's let's do just animal to be found i don't know if that fixes things let's do animal to be found and then over here animal to be found or actually no this should be just animal animal to be found okay so i hope this fixes things and it doesn't okay so i wonder why that is i might have to quickly be back and just check why this is failing after a bunch of testing i actually realized that i forgot the return right over here so what i did was i just did that animal.slug is equal to animal or sorry animal.slug is equal to rx.slug but we should either return this because this is going to return a true or false value in most cases it's going to return a false value but once it returns true that's when we want to actually return that particular animal and that's why this was actually failing so we can actually change this to something like animal instead of animal to be found and this should work perfectly fine so let's go ahead and just do that so just remember the return i was just had a just um you know my mind wasn't working for a second but now if we were to execute this you can see we actually get only that particular animal now if i were to change this to lion we get well seven-year-old lion with whatever we get whatever data that we want but you can see here now this is a great way to ask for exactly what we want now let's say you know let's add some additional logic and this is kind of the power of resolvers you can really add whatever logic it is that you want so let's say we add some sort of like gibberish you know slug and we get nothing back well there we go we can actually get null so you know what i was thinking that maybe we can add some logic that if if it's undefined um then return null but actually graphql what it does is if if it is undefined then it just automatically converts it to null so there we go so that is basically that you know that is how we can actually go ahead and query for only one specific animal and that way we can actually append whatever slug that we want to do so maybe we can append let's see we can append horse so we can append horse and there we go we get our horse data so now when we actually click on a particular animal just like lion let's say we basically in our front end can get that slug make that exact same query and provide you know that slug as the argument which we can access right over here with the args in our uh resolvers and then we can basically select for whatever it is that we want so there we go we actually did quite a bit of complex queries so that pretty much concludes really everything that we need with our cards let's actually move on to the categories which is going to kind of present a challenge of their own so let's do that in the next section all right so the next step is to work on the category page and i actually mentioned that this is going to be a little bit more complicated than just the cards itself and the reason for this is when we click on a particular category we get triggered to this page over here which shows basically all of the animals themselves that are associated with that category so if we clicked on mammals then we get all of the mammals all of the mammals only so now you can see that there's actually going to be some sort of relationship between entities the category entity is going to have to somehow map to a bunch of animal entities and we're going to get to how we can do that a little bit later but let's actually just go ahead and do kind of similarly what we've done with our animal entity but with the category entities at the moment so let's go over here let's go back to our server let's go to our um let's go to our index.js and let's go and write another entity so let's go ahead and let's say that we have a cat t gory entity we're gonna say well we need an id we also are gonna need an image we're gonna say that this is a string of course remember this is the image right here and then we're gonna say something like well okay what category does this fall in so that's gonna be a string and this is going to basically represent this right over here and then let's also have a slug because once we click on a particular category you can see that it it moves us to the products slash whatever this slug is so this is the mammal so we're gonna do a very similar thing with basically the the two resolvers that we have over here so let's say slug and this is going to be a string and i believe that is pretty much all that we need all right so that is that now let's go over here and let's basically add our um you know let me zoom back out so let's let's let's add our um type definition for our queries so now we're gonna do we're gonna call this category so let's say we want to get all of the categories so we can say well this is going to be of an array that is a category we're just going to say that everything is non-nullable all right so this is awesome this works perfectly fine so now let's go ahead and let's create our resolver now the resolver is going to look very similar or if not identical to 41 to line 41 so for this one right here so let's go ahead and let's do a categories resolver and this resolver is simply going to return an array of categories now we haven't defined an array of categories let's go to our database and let's go at the very bottom let's actually manually write this out so we're just going to do const categories and then we are going to do let's say okay so we got let's just look at our type definition just so we can see how the data should look like so we'll do an id of one and we'll do a string of one and then we're also gonna do uh an image of tiger image of tiger and then let's look at our type definition again we're missing category and slug so for the category it's going to be cats catty gory it's gonna be cats and then for the slug it's also gonna be cats all right so for the slug it's also oh sorry for the slug it's also gonna be cats so now we can just simply copy paint this four times and the reason why we're doing that is because well we have four type definitions so we can just i guess let's tabulate this a little bit better so it looks decent looks terrible let's fix the tabulations on this all right don't mind this guys this is just a little bit of fixing just so i don't go crazy there we go okay so now let's just fix up the data so the ids are going to be different so one two three and four and then for this well we have a snake so over here is a image of a snake the category is reptiles did i spell that correctly and i did not nope reptiles and then the slug is also reptiles and then over here we got ocean creatures so if you want to buy a stingray again and amazon what it does is it just puts it in one of those prime boxes and it hands it to you so we got ocean creatures and then our slug will be ocean creatures but just without these space we'll just do a dash instead uh and then lastly we got mammals and then over here we'll just say mammals similarly and over here we have the donkey for the image and over here we have a sting ray for an image okay so that is that so now what we can do is we can actually export default this so we can say categories and then we can go over here we can export it and then we can actually resolve this over here so we can say well we want to resolve this categories with the category data right over here so now we can go ahead back we can go back to our playground let's do a quick refresh now we can do categories and then we can just simply ask for the category things that we want so let's say we want the category we want the id um let's say we also want the image we execute this and there we go and that's pretty much all that we need to basically render this over here so right here we're just rendering all of the categories so there we go now maybe sometimes in certain situations we might have like a thousand categories and maybe you just want to show um four categories of those thousands so we can probably add some actually additional logic here maybe we can add some logic about you know finding the most popular categories or whatever but then that would simply go inside of the resolver in this case we're only gonna have four categories but again this is something that we can add and modify a little bit later this crash course is mainly just to get you kind of introduced to graphql and really understand these concepts if you're unders if you have a good understanding of like a restful api this is essentially what would go on into like the routes themselves so you can kind of modify them as you go all right so that is that but now once we click on a particular category we need to basically um fetch one specific category and we've done this already right so we've done this already so what we did was you know when we needed one particular animal well we used arguments so essentially now what we can do is we can do the same exact thing so over here we can do category and then we can say that this category is going to take in an argument that is a string a name of slug and it's going to return a single category and this could be nullable because maybe you provide us with an invalid string and so over here what we can do is we can add another resolver so we can do something like category [Music] and so this category is going to essentially have those arguments again parent args and context we'll talk about the other two right now but we should know what args does the middle one so now what we can say is okay well we want to find the category we want to find the category so we we're going to iterate through categories and we're going to find the category essentially where that particular slug is equal to the rx dot slug that we provide and then over here let's not forget our return that's something that we have to do and then we could just simply return the category now for uh simplicities we don't we don't really have to store this in a particular variable um if we want to do additional logic then maybe we we do have to but in simplicity's case we could just do this we can just return whatever object that is returned we don't have to store it in a variable then return that variable but for for our case we'll just leave it as such all right so now we can save this and now we should be able to query for a specific category so if i were to go ahead and do category you know we should now see slug this is what i love about graphql is it's self-documenting you can always see them over here you can see kind of these the the documentations that you can basically kind of have this is the schema you can actually look at the docs so let's say you want to go for category it tells you that okay this requires an argument that is a string and these are the things that you get back so it's it's self documenting which is pretty cool all right so slug let's just say mammals and then let's say you want the category we should get back well we get back null for some reason uh let's see why that is let's see all right so what i'm going to do is i'm going to actually just console.log just to make just to see why this is happening pretty much again even though i thought i followed all the rules i'm going to console.log the category.slug i'm going to go to console.log the args dot slug so now if we save this and we execute this we still get null but now we get undefined and the reason for this is well this should be category not categories so let's execute this again and now we get cat okay so the reason for this is look at that i have mammal over here as the slug and i'm gonna actually call this mammals that was kind of my mistake so now if we execute this there we go we get what we need there we go so i just i just kind of misspelled the uh the slug so there we go so now we can simply return this so now we are pretty much done this however again a category must be linked to multiple animals so there is actually some sort of a relationship here again if i click on a particular a category we're get prompted to this page over here that shows all of the animals that are associated to a particular category and each category is linked to a particular or each animal is linked to a particular category and so this is actually a very important concept in graphql and it involves relationships between entities we're going to actually discuss that in the next section so now it is time to discuss graphql relationships and what do i mean by graphql relationships well i've discussed this before you know when you click on a particular category what it does is it moves us to this page and it shows all of the animals that belong to that particular category so there seems to be a relationship between many animal entities with one particular category entity and that is exactly what the relationship is let's actually look at a quick diagram to kind of explain this so over here we have a category whether it's mammals fish or whatever and this is associated with multiple animals so over here from the category standpoint we have a one-to-many relationship from the animal standpoint we have a mini to one relationship so if you come from a sql background this kind of makes sense but this also really makes sense from a graphql standpoint and we have to somehow model this inside of our schema so how do we go about doing this well again in our application we have one one category that can belong to multiple animals and only an animal can only belong to one category in a more complicated relationships maybe we can have multiple categories and an animal can actually belong to multiple categories in that case we actually have a many-to-many relationship but for the sake of simplicity one animal can only belong to one particular category whereas a category can house multiple animals so again this is the relationship that we have and this is the relationship that we actually have to expose inside of our schema now how do we go about doing this well inside of the category what we can say is well each category has multiple animals so we can say well okay so we have animals and this should be an array of this type over here so we can actually add that type right in we can make it all non-nullable and that way we're saying that okay a category can have multiple animals whereas over here with the animal we can actually say that a animal can have one category by saying that okay this is this is the field category and then we can say that it has only one category and it is not an array of categories so there we go that is pretty much it however at this point there's really no way of kind of modeling this in our data for instance when we go ahead and we want to let's say refresh this we can actually go ahead and we can say uh we want to query for let's say categories and then we want basically let's say the the category itself and then we want the animals so the animals now with the animals is not a scalar type so we actually have to define the things that we need from the animals so we can say let's say we want the title or whatever the stock or the slug or whatever but when we execute this you can see here that well we get null in this case and the reason for this is because well we don't have that data inside of our resolvers now what we could do is we could simply go to our data and they simply um simply go to uh basically all of our categories and add animals in there as well so we can add an array of objects so we can simply do this let's say we want to add this right here so we can let's put a comma in and let's just add this in right here so we can add this kind of array of objects and there we go so now let's say we want to query for um let's actually query for just one particular category so we can query for the category of cats and let's say we want let's say the category itself and we also want the animals associated with it let's say we want these the slug the title and the image and once we execute this we get null for some reason which is kind of awkward i wasn't expecting that cannot read no for animal categories even though i have animals right here to find um oh that's because i didn't save it all right let's save it and now there we go okay so there we go now for some reason this this well i mean i guess i just pasted the first thing that i had in mind but obviously a cat well donkey's not going to be in the category but there we go we could do this but this is uh not too great there's actually a better way of modeling this so let's actually go ahead and let's get rid of this uh category there we go let's get rid of animals and there's actually a better way of kind of modeling this right over here so what we can do instead is we can actually use this unique identifier and basically attach it to each particular animal and we actually done this already when we copied and pasted so let's say you know for for mammals which is id of four we want to basically iterate through every single animal and have a field called category and we want to basically link that particular id to whatever the category that this animal belongs to for instance a lion belongs to the cat category so over here the category is going to be one and then over in the category section well this id is one for the cats and then similarly once we go to maybe the chalimander well this is going to belong to category number two and that is of id2 which is reptiles and we can go on and so on and so on now how do we actually go about you know okay now we have some sort of a relationship but how do we actually go about resolving this relationship into actual data well this is actually where re more resolvers come into place so essentially what we are doing here let's look at this right here for instance so over here we're saying that within this type we have animals that returns a bunch of animal and we what we could do at this point is we can essentially add a resolver so we can add a resolver for the particular categories that essentially resolves this this type right over here this animal's type this what this is supposed to return again it's supposed to return an array of animals so what we can do is we can add a resolver for the category that basically tells us or returns back what is supposed to be returned for this animal query right over here so what we can do is in here we have a query resolver well we can add another resolver called the category resolver and this category resolver will contain animals and essentially it's going to be a function that resolves basically the data that we expect to get an array of uh animals so how do we basically figure this out well this is where we are going to be using the parents so let's actually kind of console.log the parents for a second so let's actually console.log the parent and let's go ahead and let's execute this particular query so we're going to execute this query and then we get some sort of an error which is fine but you can see here that we get this object back and so this object is essentially the parent and what this parent is symbolizing is essentially the the category itself so the category that that we are trying to execute so over here the category of of uh cats so you can see here that this is cats so essentially from this what we can do is we can say okay we can get this id so we can say we can get this id and then we can basically iterate through all of the animals array and return all the animals where the id is equal to or where the category rather of those animals is equal to the id right over here so again remember we will iterate basically through all of these animals and we'll check okay if the category is equal to the parent's id then we are going to return that particular uh um object inside of an array now to do this in javascript what we can do is we can do the filter method so we could do something like return animals dot filter and we could do animal and we're only going to return if animal dot category so animal animal.category is equal to so is equal to the um the parent dot id and so let's actually go ahead and let's actually save this now remember i completely got rid of the relationship over right over here in the category section so there's really nothing about animals but now because of our resolver you can actually go back execute this and it works perfectly fine and it's actually going to work perfectly fine for categories as well so now we can just basically ask for all the animals for each particular category let's also figure out what the category is so we can say you know maybe we want the title and now we can execute this and there we go that is incredible to me all right so that is pretty much this however now we have to do it in the other way now basically we want to query for a particular a particular category when we're querying for an animal for instance you know if we are over here right now when we're looking for a category maybe we want to figure out what category this animal is in when we execute this query it doesn't work because well we haven't set up the logic yet now how do we set up the logic well what we can do again is add another resolver so we now we need a resolver that basically resolves this right over here because this is not returning a scalar type it's actually returning another type right over here involved with categories so we need the animal resolver that's going to resolve this category right over here so let's go about doing that right now so let's add a animal resolver and it is going to resolve the category similarly we're going to have parents args and then context so so far we know what parent is we know what args we still don't know what context is talk about that a little bit later let's quickly console.log the parent and now let's actually execute this and we actually are going to see okay once i save this we're actually going to execute this now we're going to see a bunch of things going on right over here so you can see that we see almost every single parent and that's because we are basically executing it for every single animal right over here um now if we execute it for one particular animal we only see one but the parent is basically going to be for every single animal that we iterate over because we're iterating through every single one so now we can say basically okay well we are looking only for one uh for one uh category so we can basically say well categories dot find and then the category we can just say well we want to return the category dot id where the parent dot category so remember the the parent is housing this category right over here so essentially you want to return the category where the category uh id is equal to that parent dot category so now we can go ahead and save this and if we execute this there we go there we go so we actually figured out how we can do this really really well and we can do these relationships with different types of resolvers remember resolvers are things that that resolve actual data so over here we're saying that um an animal or a category can return this animals field which is essentially an array of animals well we're going to need a category resolver that tells us you know what data we're actually going to be returning back so i hope that makes sense in the next section we're actually going to do a little bit of cleanup just so we can actually clean up this particular file over here because it is getting a little bit messy okay so now it is time to organize this index.js a little bit more and what i mean by that is we should probably actually have these the the schema in its own separate file and the resolvers in their own separate files as well and this is just going to clean out the index.js as much as possible and can kind of separate all of the concerns into different files so let's begin with the the schema or the type definitions now to do this all we really have to do is create a schema.js and then simply go ahead and just cut this right over here so we can just cut it and just paste it in there and then we can just do the module dot exports of schema or of sorry of sorry type definitions and there we go that is pretty much that and now all we have to do over here is basically simply import the type definitions or require in the type definitions from basically that file for them from the schema file so now if we save this well something has failed and let's see why well the reason because well gql is not defined and the reason for that is well we actually have to go ahead and import it in over here as well because in this file in the schema file this wasn't defined but now if we import it in and we get rid of the graphql apollo or apollo server you can see here now now everything is defined we can actually get rid of the uh gql on this import right over here so if we save that okay there we go we have really minified uh our our index.js and we actually separated our schema over here which is ideal now for resolvers it is best practice to actually have a folder called resolvers so we can go ahead and create a folder called resolvers and then we can have each individual resolver inside of this folder so we can go ahead and create a query dot js and in here what we can do is simply just copy basically our query and then we can just say that hey const query is equal to this particular object right over here and that is pretty much this similarly all we have to do at the very end is um let's actually go back over here we're missing a curly braces so let's go there and all we have to do is a module.exports and just export that query now we can do the exact same thing with all of the other ones like oh i guess i was missing some things for the query as well so i was missing the categories let's add those in there cool now we can add another resolver called category and another resolver called animal so let's go ahead and do that so let's do cad t gory dot js and similarly over here we're just gonna copy this and then we're just gonna do a const category and that's gonna be equal to this particular object let's get rid of this and let's get rid of that and there we go we have our one function that resolves the animal right over here okay cool so that um that does that so that's the category so let's go ahead and do a module dot exports and then we are going to export the category and there we go let's save that there we go that is done last one is the animal resolver so let's do animal dot js we're going to do const animal and that's going to be equal to some sort of object and this object we're going to export it out eventually so let's do animal let's go into our index.js and then we can simply just uh let's just paste this in right over here the category you just simply paste everything we have in there and then that is pretty much that okay so that is done now what we can do is we can actually import those into our resolvers so we can actually get rid of this whole thing right here you can actually get rid of that let's let's comment it out for now we'll get rid of it later and then we can just start doing some imports so we can import query and we'll import query and we'll require in from the resolvers when we want the query and we can do the same thing for the animal and the category animal animal and then category and then slash category right over here all right terrific so now what we can do is inside of our type definitions what we can do is we can say that well this resolver is going to be an object that's going to contain query it's going to contain animal and it's also going to contain the category so let's write that down category there we go so if we save this everything should be working perfectly now we can delete these resolvers and there we go we have completely simplified our application we have really separated all of our concerns so this is a best practice we definitely don't want to do everything inside of this particular index.js file we want to be able to spread them out all right awesome so i'll see you guys in the next section so it seems as though everything is fine at the moment our refactor seems to have worked perfectly fine however there's still a little bit of an error let's actually go ahead and showcase this error by making a simple query let's query for a particular animal we're going to query for the animal where the slug is equal to lion and then we are going to get the title and if we execute this we actually get an error message saying that animals is not defined and this is coming from the resolvers so actually when we go to our query resolver and we go over here this animal is this basically animal query is relying on the animals data and that was basically imported before inside of the index.js and that was perfectly fine when our files were in the index.js but however this is not going to work when we exported it out so what we can do actually is just simply well import everything in so we can essentially what we can do is for each resolver you can basically import everything in just so everything can work perfectly fine again so let's go ahead and do that you can just import all of our data in for each resolver but as you can imagine this can get a little bit tedious and this is not going to work because well the path is incorrect so let's let's go to the correct path so it's dot dot slash uh p so let's go here let's go here and let's go here and there we go now everything works if i execute this this works perfectly fine however you know with bigger applications this is going to we're going to have multiple multiple resolvers and we're not going to really want to just import in or require in all of the data that we require so instead what we are going to want to do is use something known as the context and this is where this context right here is going to play a huge role so essentially let's actually go ahead and let us get rid of these and so let's get rid of these for now and essentially now we're going to what we're going to do is the context is basically kind of a centralized store and we can put things in that store and then every single resolver inside of our application we'll have access to whatever we put inside of that context so if we want what we could do is we can add these you know three pieces of data inside of our context and then our resolver will simply basically use the context right over here to get access to either the animals and categories or the main cards and that is great because now we can get access to these data for each resolver and we don't have to actually require it in to the file directly now how do we do this well this is very easy all we have to do is go right over here right below resolvers and we can just say context and you can see here context and then this is going to be an object and then inside of this we can see all of the things that we want to add so we want to add animals categories and and um and or animals and categories for simplicity say what i'm going to do is i'm going to comment this out and i'm just simply going to add something like hello my friend that's all i am going to add i'm going to add hello my friend and this is going to be a message all right so this is what i'm going to add now what i'm going to do is i'm going to execute this exact same query but then i'm going to go to my query over here and i'm going to just quickly console.log the context and let's go ahead and do this now this is going to fail because animals is not defined but once we go right over here well i'm in the wrong one it should be in animal rather than um category so console.log this uh this again so let's go ahead and execute this and there we go you actually see that this message is there so now you can see that we can actually extract this now we can actually extract this even more saying being that this is an object we can actually kind of structure this out as message and so now we can say message and if we execute this again we see hello my friend so similarly now all we have to do is just simply add these objects over here and we are pretty much sent and done so now what we can do over here in the context let's go back to the context you can basically say well we we want to get out animals we want to get out let's say categories we don't need the main cards for this so now we can do that and similarly for the um uh or we don't even need the we don't even need the categories for this we just need animals we can just say okay we just want animals over here well we need the categories so we can say well we can get the categories from this now if we execute this it works perfectly fine because we put everything inside of our context now let's go ahead in the animals so what can we use from the animals over here we need the categories so we can save that and then over here we need the animals data and so we can do this and this is typically actually used with um when you're using either an odm or orm you can basically put all the models in here and then you can make like some sort of a request for instance if you're using like mongoose you can put like the user in here or i guess in this in this particular case it would be an animal and then you would do like an animal dot find or whatever so uh you would just kind of store that in the context now let's go back to what we had before all right so that is the contacts and with that right there we are pretty much done our application should be working fine with this refactor there we go that is the context and we pretty much covered what these three things are doing over here so the last thing that we have to be able to do in our graphql api is manipulate our data so at this moment this is our data but we might need to actually add more animals in for instance so right now we can look at basically this over here we might want to be able to add animals in we might want to be able to update animals we might want to add you know other main cards or other categories you need to be able to manipulate our data so we need to be what i mean manipulate is basically we might want to insert a record you might want to update a record or you might want to delete a record so in this section we are just going to worry about uh inserting a record let's say we want to insert a new animal into our website because right now all we have is what we have eight let's say we want to add another one so let's go about doing that right now well to do this we actually have to do a mutation so there's two types of things that we can do in a graphql we can actually do a query which we've been doing thus far we can do a mutation which is basically a way for us to update data update delete data whatever we actually can do another thing which is called a subscription which is just a little bit more advanced and i'm not going to get to it in this crash course so let's actually just talk about mutations which allow us to update our data so to do this we would have to do is we would have to go to our schema and define basically how our mutation is going to look because right now once we do a mutation well we have literally no options in here and when we go to docs you can see it's all queries and no mutations so we have to say that we want to kind of define how our mutations are going to look like so we can say type mutation and this is a special keyword indicating to graphql that this is going to be a mutation again updating data in some sort of way you know whether it's actually just changing something inserting something or deleting something and so we can say maybe something like add animal and then this let's say is ultimately after we add the animal we can return that particular animal itself and we can maybe do a bang saying that we always will return this animal actually you know what let's just say that we either return this animal or we return null if there's some sort of something goes wrong inside of our application so if we actually go ahead and save this now when we refresh we actually look at the docs we can see now that we have a mutation and when we do add the animal well there we go we have a add animal mutation now we need a resolver for us to kind of well resolve this right over here so to do this we are going to add a mutation resolver so let's actually get rid of all of these let's get rid of that and let's go over here and let's add a mutation resolver so a mutation.js and so this is going to be const mutation and over here this is going to be add animal we want to resolve this and then over here we're going to have parents args and then we're gonna have the context and then uh this should be an arrow function there we go and then we can just do a module.exports and then we can essentially export out well the mutation itself and so in here we can simply do just copy that and just change this to mutation and similarly over here we can change this to mutation and now what we can do is well we can put mutation right over here as a resolver so we can do mutation and just put a comma in just to make sure everything works fine okay so now basically what we have to do is we have to create an animal now remember let's look at the animal schema an animal basically kind of requires all these fields so let's actually paste it in here just so we can see all the fields that we require well okay so let's actually go ahead and ask for the user ask the user for some of these fields like the image the title um let's do like the ratings and things of that nature so let's go ahead and ask the users for these things now are we going to ask the user for a particular id probably not we're actually going to somehow auto generate in id inside of our application we don't want the user to create an id for us because well the user is not going to know what is unique across all the records we want to basically be able to create that so we're not going to ask the user for an id but then we're going to ask them but for for pretty much everything else we're going to ask them for the image the title the rating the price the description and everything else basically so how do we do that well in our schema we can simply go over to uh over here and just simply ask for well literally everything so we can just say we can just pretty much copy all this and we can say that hey we require all these things right over here and this category itself is going to be a string rather than a category later on in the query it's going to resolve itself so essentially here we're saying that okay well we need you if you want to basically do this mutation we need an image we need a title you can provide us with a rating if you want we need a price we need a little bit of descriptions and we need a slug we need some stock and we need a wall and you can provide us with on sale and let's say we absolutely do need a category so there we go we can actually go ahead and save this everything should be working fine and now when we refresh this now we can actually see all of the arguments that we need to provide so we can basically provide image and blah blah blah so let's actually go ahead and um let's go ahead and let's go over here and let's basically extract out everything that we need so essentially um remember the args themselves are going to contain everything that we need so let's just say um let's just extract it out using a little bit of destructuring so let's destructure this out and let's say we are going to get all these things where are they all these things right over here i'm just gonna quickly copy and paste them and then we can let's do a comma comma comma comma comma comma so these are all the things that we're going to extract from the arguments so for instance now we can do like a console.log of let's say the image and let's go ahead and um provide some sort of image in fact we're going to actually have to provide a bunch of things so maybe we can actually do a copy and paste of this as well and then let's just just add a bunch of things in there so a title a rating that is a float uh let's add a comma here a comma here a price that is let's say oh this is also has to be a string and then this is going to be an array of strings i'm just doing a bunch of gibberish in here let's do a slug of alligator let's do a stock of 2 or 22. sure and then on sale of true and then a category of let's say 2. so once we execute this it is going to fail because um we're missing some parentheses so let's go ahead and let's add some parentheses and then over here we have to basically specify what we want because we basically say that we're going to get back a a animal so now we can execute this we get back no but you can see in our server nothing happens because i always forget to save let's execute this again you can see here that we actually get back the animal or the image itself so we actually can get back to these arguments so now what we can do is we can just basically construct the new animal so let new animal equal to all of this right over here and then we also need the id now the id we're actually going to have to kind of generate ourselves so what we're going to do is we're actually going to install a package that kind of generates ids for us and this package is called uuid so go to the go to the same directory that same server directory in the start and then in the server and then do a mpm install uh uuid and so this is just allow us to kind of uh add a random id that is going to be pretty much unique across everything so let's go ahead and let's do um const is equal to require and then we'll do uuid and now over here what we can do is um i believe it's going to be called v4 i hope this works sometimes i always mess this up but you can say now that the id is called v4 or v4 just a certain version of the uuid don't worry all you have to notice that this function is going to generate kind of a random string so there we go we have created our new animal so let's go ahead and console.log this and let's execute this again all right so now once we go back to our server you can see that we get this new animal with this new random id so now all we really have to do is basically access the context over here which is the animals and essentially now all we have to do is basically push that new animals into this animal database so we can say animals.push new animal animal.push new animal and then after we push it so at this point we basically pushed it into it and then we can basically return the new animal because we basically promised that hey that's exactly what we are going to get back so we can return back the new animal so there we go that is pretty much that so let's go ahead and let's execute this let's change this to let's say i don't know um well i guess i'm using alligator so let's change this to alligator and over here also alligator so let's actually go ahead and execute this and there we go so now we can see that we actually get back this description and it seems like everything is working fine but now when we actually go ahead and make a query for all animals and let's ask for specifically the oops let's specifically ask for the image because the image is going to contain basically what that animal is now remember before we didn't have anything regarding an alligator but now once we execute this it says here animals is not defined for some reason animals is not defined i wonder why that is let's see let's go to query over here and it's saying that animals is not defined oh the reason for this is because well we have to add parents args and animals in here as well for actually forgot about that we have to do the same exact thing inside of this right here but for categories so now if we execute this the only issue now is that we restarted our server completely so let's actually go back and let's add this mutation so let's go back and let's add this mutation so and let's ask for the image back so we can go ahead and we basically added this and now once we go ahead and go for the animals not the animal animals and let's say we want the image and we execute this you can see here that now alligator is actually a part of our database now using this mutation we were able to add another animal and that right there is the power of mutations so we're going to be doing one more mutation which is basically allow us the ability to delete a particular entity in our database later on maybe for you for your sake maybe you can think of a way to actually update specific information but i'm not going to go into that level because again once you can figure out how to add and delete and work with mutations you can probably really customize it to whatever it is that you want so let's do that in the next section so the next mutation that we are going to write is going to give our users the ability to delete certain animals inside of our database for instance let's say they wanted to well delete the gorilla but we want to give them that ability so let's go ahead and do that right now so to do that what we have to do is we have to define our new mutation type right over here so we can say that a new mutation what we could have is something like remove animal and for the uh for the arguments we can say that well we can either use the slug itself or an id i say we use an id and essentially again the the argument is going to be used so we can identify what particular animal object that you want to delete and then we can go ahead and delete that and let's say that well we will return the animal itself that you want to delete actually you know what there is actually no point of returning the animal itself let's just return a boolean indicating true or false if if the thing was successful so let's go ahead and let's do this and let's actually add an exclamation mark over here so now inside of our mutation what we can do is we can basically do remove animal and over here we can have parents the args the args is going to basically contain the id and then the context which is going to contain the animals and this this animals is actually what we are going to be updating so let's go ahead and let's update that so now what we want to do is we essentially want to find the index where this animal object that we want to delete exists and then what we want to do is we want to basically get this animal's array and splice out to the object at that particular index so for example let's actually go over here let's say we are trying to delete the the horse for instance well we want to find the index where this horse object exists in this case it would be let's say 0 1 2 3 and 4. so this would be the fourth index and we can use the splice method to splice out a particular element at that index so we would just splice this out completely and so this is what we're going to do now to find the index we essentially what we what we would have to do is iterate through every single element and identify the id that corresponds to the id that was provided to us in our arguments so we can do something like this let index equal to we can do animals find index so this is an actual method and then over here animal and then we can do something like return animal dot id is equal to the id that was provided so the first thing that passes this condition is going to get that index and basically put it inside of this value right over here then later on what we can do simply is something like this we can just do animals dot splice we want to splice the object at this particular index and we only want to splice one object so essentially this is saying okay well what from from from where do you want me to start the splicing and then the second is basically saying okay how many uh elements do you want me to delete after that uh initial start so if i say two then we delete the first one and the second one but if i say one i say okay just delete that first one so that's why we save one because we only want to delete that one and in this case we're always going to get some sort of successful response so we're just going to do something like return true so let us go ahead and let's try this out so let's go and do a mutation let's do refresh this we'll do a mutation we're going to do remove animal actually before we do this let's go make a query just to see what animals that we want to delete so let's do animals and let's do image and let's do id let's say we want to delete the poor gorilla so we would just pass in this id over here the id of four so now we can do emutation and then we can say remove animal and this id of four and simply well we return back true so we can just execute this and there we go we get true back and now when we make the exact same query we actually don't see the gorilla anymore it's completely gone because we deleted it and that right there is the power of mutations i encourage you guys to continue playing around with them and maybe figuring out how we can update certain data it really works the same exact way maybe for updating data what we would have is something like this we would have a we would have you know maybe you know update update update animal and so the first thing that we would need is we would need some sort of unique identifier to identify what object that we're trying to update so id and then what we would say is well okay so the next step is we need you to provide us with the things that you want us to update uh us with so let's say they want to update the the description or the title or the rating so essentially what we would have to do is we would have to basically pass all of these things in over here so we would have to basically pass all these things over here and basically make them non-nullable and essentially what we would say is okay if things if if if we actually provided a particular value then we are going to update that value but if it isn't provided then what we're going to want to do is we are going to essentially use the existing value so that is kind of a little bit more complicated um but i highly encourage that you guys kind of look into it i'm not gonna do it just for the sake of this crash course it is getting a little bit long so there we go and that is mutations and that pretty much concludes our api now let's actually move on to the front end and let's actually start kind of interacting with our api in the front end so let's go about doing that so we finally built our graphql api but now what we want to do is we want to essentially be able to make queries to our api in the front end so now from now on we're going to be dealing with the front end and interacting the front end with our server so if you're not interested in working in the front end well you can pretty much call it a day you've learned a lot of graphql and you can just work on the server side and just let somebody else handle the client side but if you're interested in learning the client side as well and how the client interacts with our graphql server then continue so right now if you go ahead and do an npm install on the client and you go ahead and run it this is all we get all the data is not present at the moment and essentially the way that we are going to connect our client to our api our graphql server is through apollo client again there's multiple ways we can do this and we've actually discussed this a little bit before but apollo client in my opinion is one of the easiest and is the most popular approach of connecting your a client to your server and we've used apollo servers so might as well use apollo client as well so let's actually go ahead and use apollo client to connect our react application to our api now if you're not familiar with react that is okay the approaches that we are going to take is going to be very very similar with things like vue or angular or nux or next or anything of that nature there's apollo implementations for these things as well or libraries that are very similar and at the end of the day again everything maybe syntactically might be a little bit different but overall it's going to follow the exact same concepts so let's go ahead and let's read the documentation so the first thing that we have to do is we have to install apollo client and we also have to install graphql so let's copy this and let's go to our client let's quickly go right over here let's go right over here and what we're going to do is we're simply going to stop our or you know what we're not we don't have to stop our running server all we can do is we can open up a new terminal and we can just cd into it let me just expand the size of this terminal so i'm going to do cd into the starting directory and then into the client and then what i am going to do is simply do a mpm install of apollo client and graphql now you can go ahead and do this i actually already did this beforehand just to speed up the video so once that's done you can kind of continue so let's look at the next steps so the next step that we have to take is well we have to create the client and essentially what this step is doing is it's basically saying okay well okay you want to connect it to a graphql api but you have to tell us well which graphql api you want is connected to so let's actually go ahead and do this we're going to do this inside of the index.js in the source directory so let's go over here let's open up the index.js and then over here what we're going to do actually you know what we're not going to do in the index.js let's do it in the app.js and so if this is a little complicated to you you don't understand what's going on don't worry we're we're if you're moving on with the client side i i do kind of expect that you know a little bit of one of the three frameworks whether it's view angular or react if you know one of them you should probably be able to follow along with the other one so if you're familiar with vue you should be relatively familiar with what's going on with react and similarly with angular as well so essentially we're going to go over here to the app.js and we're going to do those imports so we're going to import uh what are we going to import so we're going to import something from at apollo client and that something is um is going to be apollo client which is allow us to create our apollo client and uh i forgot what was called it was something about caching in memory cache in memory cache and essentially now what we're going to do is we're going to create our client so we're going to basically follow this step right over here so we're going to go over here we're going to say const client is equal to new apollo client so we're creating a new instance the uri is going to be the uri of our server in this case it is oops in this case it is actually let me go ahead and quickly uh copy this and let me paste this in here there we go i'm only just doing this for my services but essentially what we're going to do now is the the api itself is going to be this one right over here so we can go ahead and this is the api that we want to connect to and then for caching so so essentially what uh graphql does is it supports caching so once we make a request to our api we don't have to make the same request again what we would do is we would just simply cache that data in memory and then we would uh basically get that data back and this is essentially what this in-memory cache is doing and that is completely identical to what is happening over here except this is a uh this is something that we have to instantiate new in memory cache all right there we go so that is that and now we have to tell all the components within our react application about this client and this is where we would use the apollo provider and so over here we want to collect connect our our essentially our client our api to this react application and so we would use the apollo provider component so over here we would say apollo provider apollo provider and then we would basically wrap all of our components with the apollo provider component so we would go ahead and wrap all these components with the apollo provider component and as a prop we would pass in our client so as the prop the name is going to be client we're going to be passed in the client that we have just created and now we basically have access to all the data inside of our graphql api with just this one single endpoint so let's go ahead and save this and let us see oops sorry so let's go ahead and save this and now okay you can see that nothing has changed let's go ahead and actually render those cards that we saw with our hero so let's go ahead right over to our components and we're going to go to the main hero page and essentially what we want to do is we want to render those cards remember those cards with the title let's actually take a look at how they would look like in the graphql playground so the main cards and we want the image and we also want the title so if we execute this we see here that main cards is not defined and this is an issue of our this is an issue of our server let's quickly resolve this this is probably a context issue so let's uh see why that's happening over here in the query uh we're saying that main cards is not defined and that's because well we have to access it in our context so let's do main cards so now if we execute this there we go so essentially we basically want to render the cards with this information so this image and this uh title so let's actually go ahead and do that so now we are in the main hero component not the css but the js and let's actually go ahead and do this and essentially what's happening here is once we can get the data you can basically put the data right over here and it's going to iterate over that array of data which is basically this over here this right here this array and it's going to basically generate our cards currently it's just an empty array so let's go ahead and get this data now how do we get this data well we would get this data using a special hook this is why we need to use function based components for this we're going to use a special hook from apollo client called use query so use query you can see that there's multiple hooks but we're going to get use query and this essentially allows us to query our data and now we also have to define the um the the kind of graphql uh um graphql layout this right here basically the schema that we basically want and so over here we're also going to have to use graph or gql so let's go ahead and basically let's create that schema right over here so let's go make that query so over here we're going to do something like const and essentially you know our cards data we'll do cards data and that is going to be equal to the query and then this query is going to accept basically the structure that we want over here and so this is going to be graphql with these tags right here and then we can basically paste this in there if we want to you can basically paste this query in there so this is the query that we want to make so there we go let's just improve the syntax a little bit more and there we go so there we have it so let's actually go ahead and just console.log those console.log the cards data and so essentially what we're doing here again this is how we would do basically the exact same thing but in our react side you would just use this use query hook and then we would wrap our query inside of this particular hook so let's go ahead and we will save this and then we will console.log the cards data so let us go ahead and go to amazon and if we refresh it seems like nothing is failing which is great let's go to our console and we can see that we get a bunch of objects so let's look at the first object you can see here that we have a bunch of things we have something like data well the data at the moment is undefined and over here we have error error is also undefined and then if we kind of continue looking we see something like loading and over here it says loading is true and so the reason why the data is undefined is because it takes a little bit of time for us to fetch our data from our api and therefore we are currently in the loading state we're not in an error state we haven't hit that yet and we haven't had any data we're just loading so now once we kind of go on over here you can see okay we're still loading so this is true but then at the very end well you can see here that we're not loading anymore we haven't hit an error and there we go we have our data and that is exactly what we need so over here what we can do instead of just saying card data you can basically destructure out these important things loading error and the data and now what we can do now is if we are in a loading state we can say well if loading we will return maybe some sort of spinner or whatever indicating that we're still loading in this case i'm just going to have loading dot dot so over here we have just we're just loading and then you know maybe if we hit some sort of error we can say return you know some error happened and so essentially if we're loading we're only going to return this over here we're not going to return any of these other ones if we hit an error we're going to return this over here and then if we are basically we hit our data then we basically hit this over here now remember how our data looks like our data i hope this is clear let's zoom in a little bit zoom in some more so you can see here our data at this point contains the main cards so essentially what we can do now and the mean cards is an array itself with the image and the title because that's how we specified our data so now what we can do is we can say here instead of an array an empty array we can say data dot main cards and if we execute this there we go okay so this seems like it is working all right so one thing that i am missing is i don't have a key prop over here and another thing that is odd is that the images don't seem to be rendering now let's go ahead and let's see why these images aren't rendering so we got card dot image and so okay and the reason why the card.image is not rendering is because let's actually go ahead and console.log this again so console.log the data uh so the reason why the card is are not rendering is because i mistakenly just use a i m g instead of i about the word image as you can see right over here so if you go ahead and change this to just image you should see the images rendered there we go and we can add a key later on but whatever so that is basically the first step let's actually move on to the next step where we can actually render our other cards so i'll see you guys in that section okay so now let's move on and let's work on the other thing so like the the categories and the cards themselves let's actually work on the animal cards first because then those are the most visual so let's go ahead and let's go about doing that so to do this what we have to do is we have to go to our landing page and so if we go to the pages directory right over here and then we go to the landing page we can see here that we have our main hero which is this over here we have our category display and then we have our cards display and this cards display takes in a prop that contains basically an array of objects that contain all the information about our animals in this case right now it is just an empty array so we have to actually fix that at the moment so let's go ahead and let's make a request to our client and let's basically ask for specific data now in the last section we used basically let's go um let's go back to what we had before i believe this was in the main hero what we did was we actually appended the graphql schema right over here our request our query inside of the use query best practice is actually to do something like this you can do something outside of the function such as like fetch you know main cards and we basically set that equal to this query right over here and then we can basically go right there and just put in fetch main cards and that just makes it a lot easier and better to visualize so we can actually go ahead and we can see that this results in the exact same thing so this is what we're going to do with our landing page so let's go ahead and let's import in use query and graphql or gql you know what i mean from apollo client and over here we're going to make a request to get basically the information that we need for our animal cards now remember our animal cards contain a a lot of different information so over here we have like the the image the id the uh you know the stock the rating the whatever uh you know and there's actually certain things that we don't need for instance we don't need the stock we don't need the description we do need the image for the card so let's actually go ahead and select for the things that we need so we do need let's say we need the image let's say we also need the id even though really nothing is visually displaying we need the price and we need the slug and we need the image so these are the things that we need so this is the query that we are going to make and that way we only get the data that we need so let's go ahead oops i always go the wrong way so let's go ahead and let's say const fetch or we could probably call this something like animals query that's probably a better thing to call it and then we can just do this and then over here we can basically say well give me the loading the error and the um and the data from use query and then of this particular query the animals query now i actually kind of brushed through this and i haven't i don't really describe this i just realized that all this is typically in capitals so this is just kind of a common convention it doesn't have to be this way but this is a common convention for a query or a mutation to be all in capitals and just certain words to be separated by an underscore so that's just a common convention but it doesn't have to be this way but again common convention so that's what i will do so there we go so now we get our data so now what we can do is we can do something like well you know if it is loading well let's return hey we're still loading again in a real application we would probably have something more complex maybe some cards that appear that they're loading or some sort of spinner but later but for this we're just going to do something like this so if error we're going to do a div we're going to say error and then you know if we pass all these then we're over here and essentially now what we're going to do is we're going to say data dot animals and essentially what this is going to be is that those array of animals so now if we actually pass that in there and now if we go to let's actually go to the cards themselves i believe the images are not going to work and the reason why the images are not going to work is because i misnamed them over here so let's rename them back to image and there we go so i believe now if we go to our component we see our cards however we are we do seem like we're missing the title and the reason why we're missing the title is i think because we're not asking for it so let's go ahead and ask for the title now we get a little bit of a loading state and there we go now we have our title and we rendered these images so now let's go ahead and do the exact same thing but for the categories now in this section if you go to our landing page you can see here we have a category display and this is basically not using any props even though we could have potentially appended the category query right over here we could have done something like category and just added it as a prop for some reason i decided not to do it that way so i mean this would be a perfect example of actually under fetching i think actually that might be a better approach so i might actually refactor the way that we're doing things so we can actually pass this in as a prop just because it is better actually you know what let's just continue but you you can kind of think of it um we can have over here we can actually append categories and have our query as well so we don't have to um you know have the the results of actually under fetching all of our data but for the sake of practice let's actually go to the categories not the categories page but the categories display and let's go ahead and uh let's uh let's let's do this thing all over again so let's do import use query and then graphql and then we're gonna get that from oops we're going to get that from apollo client there we go and so now what we're going to do is we're going to define our um our our query so we're going to say this query is the catigory's query and so this is going to be equal to graphql and this is going to be a query and over here we're going to want the categories and we also want from the categories the category itself the image and then the slug so let's go ahead and now over here simply again we're just going to do another console.log we're going to do a const and we're going to do loading error and then we're going to do data and this is going to be use query and we're just simply going to paste this right in there okay and what i'm going to do is i'm going to just quickly paste these two error handlings right over here so i don't have to copy them out again and then over here we can just say data dot categories that's going to be the map and then there we go again um please please keep in mind that we have to change it from image to images so there we go and there we go so that is our landing page now one problem when i go ahead and click you can see here that i don't really have the data associated with our application so let's actually go ahead and let's fix this right about now okay so the next step is for when i click on a particular animal i want to be able to see the details associated with that animal right now i get really no data other than maybe this this right over here but this is really just fixed into place later on we actually want to dynamically generate this data so let's go about doing this right now now remember if we want just one animal we already have a query set out for this something like animal and then we would provide the slug so the slug would be something like well lion or whatever and then we would ask for the specific data that we want back so we have a query for this and so what we can do is we can just simply copy this exact same query so let's go ahead and let's do that and so this basically this right here is a separate page as you can see by the route uh let's go to the route over here as you can see this is a separate page and this is the actually the uh the animal page so let's go to the animal page and let's go ahead and let's make a request to basically get our data so now we are going to do simply like we've done before this is kind of getting a little boring but it is it is this one is a little bit more interesting and we'll see why actually and then from uh apollo client let's just get rid of that extra space and now what we want to do is we want to make a request and so what kind of data do we expect to get back well we expect to get back the image so right now we don't have an image and we also expect to get back the title which is something that we don't have at the moment so let's say title let's say image and let's say we also need um not the id sorry the image let's say we also need the stock so that's something that's very important so these stock and then we also need the description because right now this is just uh generated statically so let's say the description as well and we also need uh the price over here we need to display the price and i think other than that that is pretty much all that it is that we need i don't think we need anything else at the moment so we just need these things so let's go ahead and we would execute this and okay great so let's actually copy this and let's put it in over here so let's do animo query so the animal query and then this is going to be equal to well graphql and then the query however there's a little bit of an issue here right now this is always lying we hard-coded line and this is not really the way that we want it in our application we want to essentially pass in whatever this particular slug is right over here into our query in our application now we can actually go ahead and do this by first using some sort of react way of getting that slug so over here i get that slug with the use params hook essentially what this allows us to do is just to get the slug don't worry about it but now what we have to do is we have to somehow pass it in to this query right over here and this is actually not too difficult to do this what we would say is we would actually specify the word query and then we would have parentheses and then we would say that we are expecting a dollar sign a some sort of variable and this variable is called slug and we specify a variable in graphql with the dollar sign so now we're saying dollar sign slug is what we are expecting to get somewhere inside of our query and then this is expected to be a string and this is uh this has to be a strength so so once we get this variable what we can do is we can actually place it over here okay so this this is cool but how do we really pass in the variable inside of this query well once we do our uh our use query remember we get loading error and data we can basically define the query with the animal query and then we can have a separate object that contains a bunch of other configuration this object one of the configurations is variables which is a separate object of its own and it's going to contain all the variables that we want to pass in now in this case we want to pass in the slug variable so we can say slug is equal to slug again we're not going to pass in the dollar sign but essentially what graphql is going to do is it's going to append the dollar fine later on so we're going to say slug is equal to slug and that way whatever the slug is we're going to be able to pass that in but now because this the key and the value are the same word uh in in javascript we can just simply do slug on its own and that is exactly the same thing so let's go ahead and just console.log this data and let's see what goes on so over here i'm expecting data based on the chameleon so let's go ahead and let's inspect this and over here we can see let's refresh this once more and there we go we get some animal data and this data is well a chameleon this is all about the chameleon now if i go ahead and i do elephant i get some data and this data is well about the elephant and there we go that is exactly how we would do this kind of dynamically so let's actually go ahead and let's just render our data in so let's just do these conditional checks you know if error if loading then just return loading and then if error then return error and now over here if we pass all these things and we can say basically data.title so now we can actually see the title once we refresh i don't know what's going on here so oh sorry it wouldn't be data.title it would be data.animal.title mybet data.animal.title and now we see this over here we can say data.animal dot stock so now we should be able to see the stock there we go uh over here what we can do is instead of and dynamically or just like you know we can dynamically render this by having some sort of an array so we can say data dot animal dot description and then we can just say dot map because this is an array and we can say uh okay is this description or descriptions okay should be descriptions actually but whatever we can say okay for each description we're going to map over it and we're going to return an li of that description so now we can save that now if we refresh this it should be exactly the same but you can see it's rendering even though we don't have it a few more things that we're missing we're missing the price so we can say data.animal.price and there we should see a price right here cool last absolute last thing is the image let's figure out where the image is uh let's figure out where the image tag is right here okay so now we can just add a source of data dot animal dot or data or sorry this would be animals because this is uh if you don't know what i'm doing here we have an animals object that we imported let's go let's go find this animals object this in our assets so essentially here i basically have a bunch of images and i've i'm basically export defaulting them and i'm basically importing them over here so now what we need to do is we basically need to say well i want uh if it whatever image that i want i basically say animals and then brackets whatever the name of the image that we want so we can go ahead and do something like this if we want if we wanted the lion we would say lion and there we go we would get the lion however in this case we actually don't want the line we want to dynamically put it in there so it would be data dot animal dot image save it in there we get our beautiful elephant there we go so that is that that is terrific and that works perfectly fine and we're going to do something extremely similar with the category section so once we click on the category you want to be able to see those categories highly encourage you guys to do this on your own but if you want to kind of continue following along i'm going to start doing it right now so let's go to the uh category page so this is the category page and over here we are going to make another set of calls so here we're going to do kind of the catigory query and this query is going to look a little something like this so let's go back to the playground and it's going to look something like this we're going to have you know well the category we're going to specify the slug let's say the mammals category and then we're going to ask for the things that we want so in this case you know we want the id we want the category itself you know to kind of explain what it is maybe we even want the slug but one thing that we also want is all of the animals associated with that category so we can display the cards so over here we can say animals and then we can say well we want the id we want the title we want the price and we want the image so you can go ahead and execute this and yada yada we get all of our data so let's go ahead and let's just paste that query in right over here again we want to be able to dynamically generate this so we would just say query and then we would say dollar sign slug and this is going to be a string bang and then over here we're going to say that we're going to use this right now okay cool so now same exact thing you can do const did i import uh use uh i didn't import it one thing we can actually do uh let's see if this works the one one thing that we can actually do is we can actually define use query actually it didn't work so might as well just import it then our import use query and then graphql from and then let's do let's do uh this is well from at apollo apollo client and now over here we can just do use query and what we're going to do is we're going to do the category query and then we're going to specify our variables like we've done before and this is going to be the slug of course we want the error the data and the loading and let's see if i can just quickly copy and paste these things over here you know if this happens so one thing that is important is we actually have to do this and the reason why if we don't do this is let's actually go ahead and let's try to actually render data in here so data dot um this is going to be data dot category or sorry sorry this is going to be data dot yeah data dot category dot animals this is rendering our animals if we actually go ahead and execute this and then we click on this it ends up failing and the reason for this is because well it's saying cannot read property category if undefined and at this point data is undefined because well data is going to be undefined until we're able to actually resolve our query and that's why we actually need this so let's go ahead and let's put that in there and then over here we can put in the actual category and if we refresh this it shouldn't fail anymore it is so objects are not valid uh i wonder why this is invalid this should be not an object let's actually console.log our data just to see how it looks like so let's console.log right over here just to see why this is not behaving the way that we want it to behave so this console.log we see our categories and so it seems like it's category and then animals right over here so i'm a little confused as to why this isn't working actually uh data because this is an array and not an object so in my opinion this seems like it's working i might have to uh pause the video to see why this isn't um okay i'll pause the video to see why this isn't working this should be data.category.category and i think that's what really confused me remember i went ahead and i did this again remember if we actually go ahead and we console.logged our data this is category and then over here we have another category right over here so we were actually returning just category and that's why it was failing because we were returning a simple object so there we go we have built out our entire application this is pretty much done the last thing that i am going to add in this application that i didn't introduce is maybe a little bit of a form that allows us to add new entries in and this will just kind of teach you how to actually use the mutations within react so we're just going to really really quickly do this i'm actually kind of doing this on the fly i haven't prepared it but i thought it would be important to kind of talk about that so that's what we're going to do in the next section so the last thing that we're going to do is we're going to see how we can actually apply a mutation in the front end and i was thinking about doing a form but just to make things a lot easier and quick let's just do a simple button that essentially inserts a particular piece of information into our data a new animal into our database so let's go about doing this so what we want to do is we want to use some sort of mutation to add an animal over here so essentially well we have a mutation for this we have our add animal mutation and let's say we want to add a real animal in here so we want to add um you know an animal with uh with basically an image of ostrich so this is a real animal and then we're going to say that the category is where we're going to say belongs in the cat category because we don't have a bird category at the moment and we'll say what else what else do we need do we need a title so let's do a title this is a really cool ostrich and then i'm gonna let's do a stock of like 13. a price that is going to be you know 32 000 i wonder if we're missing anything in the description we're not going to have much of a description in here uh let's do a rating of well 3.5 and then a slug of ostrich so ostrich and then am i missing anything else i believe that should be good so if i actually go ahead and execute this it says that i am missing something so field did you need did you mean add animal so field at animal of type must have a selection subfield do you have oh okay that's fair so let's say we want the id itself so we can execute this and there we go we executed this mutation and now because we execute this mutation if you refresh our react app we actually should see this ostrich and there we go so that is basically the mutation but now we want to be able to do it in the client side so let's actually just quickly down and dirty just create some sort of butting that allows us to insert ostriches into our animal array so what we're going to do is we're simply just going to go to this landing page and we're just going to create a button called add an ostrich and so this is going to be down and dirty but i just don't want to create multiple forms and really worry about the react side really when we want to make mutations maybe we would have some sort of form that gets data from the user and puts it in the mutation itself but in this case we're just going to do this but it really is very similar to the way that we would do it with a form or anything of that nature so let's go ahead and let's refresh this and we have this button called add an ostrich right here in the bottom so let's do a mutation now to do this we would do something very similar we would do over here and we would say add animal mutation and this is going to be graphql and essentially what we're going to do here is we're going to copy this mutation and we're going to paste it in there now of course we don't want to hard code these informations in because they could be different so what we're going to do is we're going to say well we expect some variables so for instance we expect a variable that is a string we also expect a category that is also a string we expect a title that is a string and then we expect a stock which is an int and then we expect a price that is a string and then we expect and this oh sorry this by the way all should have dollar signs in them so dollar sign dollar sign dollar sign then we expect a description so dollar sign description that is an array of strings and then over here we expect a rating dollar sign rating that is a float there's a float this we don't have to have a bang in it and then we also expect a slug that is a string and then over here all we would have to do is just simply say instead of hard coding it in there you can just say well we would use this and then i'm just gonna have to quickly copy and paste everything in there so let's do category i don't know what would be faster me typing it out or just copying and pasting let's do stock and then price and then description and then dollar science rating and lastly over here you can do the dollar signs luck okay so that is that that is basically our mutation right over here so now what we can do is we can actually use a new hook called used mutation and so essentially over here we can basically set up this used mutation right over here this is going to be set up a little bit differently instead of an object we are going to use an array and this is going to be equal to the used mutation and we're going to pass in the add animal mutation and over here essentially what we are going to be doing is we are going to say well add animal this is going to be the function that we want to call when we this is the function that we want to call when we uh go ahead and and basically want to add some sort of a mutation so let's go about doing this for right now so essentially when we click this over here so let's have a on click event essentially we want to execute a function we want to basically execute a function that calls the add animal and then over here we can just basically call it but we can also provide variables so we can say well we want to provide some variables and what are these variables again these variables can be dynamically generated from our client but in this case these variables are going to be exactly these guys right over here so let's go ahead and let's paste in these variables and this is exactly what our variables would look like so that is pretty much it that's how we can actually execute a mutation so let's go and save this and now let's refresh so let's go and just refresh our server itself so to do this all we have to do is go to any file in our server and just save this again and now once we go over here we shouldn't see our ostriches anymore so now when we click on add an ostrich well we can click on it and then we can refresh our page and there we go we have an ostrich you can see that this works again this could be completely dynamic we can have a form but for the sake of simplicities this is what we are going to do so again we would just have some sort of query we would follow pretty much the same steps where we define um all of the things associated with this ostrich right over here and then we would basically use the used mutation hook and then we would call that hook with the variables associated with it so there we go we have learned a lot about graphql hope you guys have a great depth of knowledge i hope you guys enjoyed the crash course it was a pleasure making it and i'll see you guys in the next one
Info
Channel: Laith Harb
Views: 14,785
Rating: 4.9927797 out of 5
Keywords:
Id: CFrKTrMJIBY
Channel Id: undefined
Length: 179min 54sec (10794 seconds)
Published: Mon Feb 22 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.