Complete GraphQL API tutorial using Apollo Express and MongoDB

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay guys so welcome back again so in this video let's see that how do we build an api using graphql and for that we'll be using the apollo express server that is we'll be using the apollo framework with our express backend so this will be a full-blown api with all the correct functionalities that is we will be creating reading and updating and deleting all the records inside our database and for the database we'll be using mongodb and for that we'll be using the mongoose orm so what i'll prefer here is this that i'll keep the model that is our database model to be very simple and for that i am choosing a post model which should only have a title and the description of the post and i will try to keep this video as simple as possible so that you can have your own api up and running using graphql so without wasting any time let's dive into our code and let's see that how do we implement it okay so here what i've done is that that i've created this empty directory called apollo gql express and avl is here we see that the directory is currently empties so let me clear out so firstly what i'll do i will create a file here called server.js so let me create a file called server.js and now what i am going to do i am going to initialize the new npm project here so i will do npm and hyphen y to keep all the defaults so now let me clear out and now we have this these two files here that is package.json and server.js so now let me install in a couple of dependencies here so firstly i'm going to install express because we are using a polo server with express and then we need to install the apollo server express library that is apollo server express and then we need to also install the graphql library because we are going to play with graphql and then we need to also install this mongoose library which is an orm for for mongodb so now let me install them and it will take a couple of moments to install and then what i am going to do i am going to install one more library that is called nodemon which is a dev dependency so let me do npmi hyphen d to install nodemon and it simply restarts the server on dot js changes that is whenever we change our dot js files so now let me open this project inside vs code and now we see that we have the package.json file ready and now here what i'm going to do inside the scripts thing i'm going to create my own script that is called div so it should simply say nodemon server.js simply like this so now let me save this package.json and now let me simply close this package.json file so now firstly what i am going to do i am going to initialize our express server application that is the apollo express server for graphql so let's go to the server.js file and here i would be importing a couple of things so firstly we need to import express so we'll say require express not something like this but it should be like require express and we are missing a tick here like this and then from the apollo server express package we are going to import something so it should say require apollo server express like this and then what we need to import we need to import the apollo server from this package and then we need to import the gql tag and if you are wondering that what this gql means this simply is for later syntax highlighting and auto formatting for with prettier and the prettier is extension inside vs code but this gql tag also helps us in statically analyzing our graphql queries so now what we will do we will create our type definitions and our resolvers for this apollo server so let's simply create it here and these are only for demonstration purposes here that i am creating here inside this file but eventually they will be going inside their own files so cos type devs equal to something and this should be equal to gql like this and then we open the back text like this and here we are going to write our query so firstly we will define the type to be query like this and here we simply have a query called hello and it simply returns as a string and mind you guys that if you don't know anything about graphql then i would highly recommend that you watch my video that is linked above and it's in the description also that is getting started with graphql and it is for execute printers so even if you don't know anything about graphql you will be learning a lot about graphql from that video so now let me create our revolvers here so const resolvers equal to something and this should be equal to the query resolver that would resolve our queries and here we can simply say hello like this and this should be a function an arrow function and it should simply return hello world so return hello world simply like this so now we have the type dip seven we have the resolvers so now to start the server what i am going to do i am going to create an async function here that would be called start server async function start server simply like this and then at the end what i am going to do i am simply going to say start server like this so now let me save this and now whatever we do inside this start server thing would initialize our apollo express graphql server so firstly we need to initialize our app from this express thing which we initialized here or we required here so we will say const app equal to not required but it should be like express simply like this and then we will say apollo server equal to new apollo server and this apollo server comes from this package that is apollo server express and here we have required it at the top and now here we need to fill in a couple of things firstly we need to provide in the type diffs so like this and this should be equal to type diffs simply like this and then we need to provide in the resolvers and the resolvers is called resolvers itself so now since we are using modern javascript so what we can do since both the names are same we can omit the second thing here and we can keep it like this only so it means the same thing as it was before simply like this and now what i'm going to do i'm going to start the apollo server using await so i'll say await apollo server dot start simply like this and even if you don't do this thing here that is apollo server dot start then also the server would start listing but it is highly recommended that you should always do apollo server.start before listening to any port from your express application so that the schema has been loaded and the server will start hooks have been called and if either of those processes throw start will throw as well so therefore it is highly recommended that you should use apollo sidewalk.start before listening to app on any port and now what i will do i'll simply say apollo server dot apply middleware and the middleware we want to apply would be our app which we have created here so it should be called app like this simply like this and by default it takes the forward slash graphql as your graphql path that is localhost port 4000 forward slash graphql would be your graphql path and now finally what we will do we will simply say app.listen and here we provide in the port so let me provide in 4000 and then we have the callback here and here we can simply console.log that server is running on both 4000 so running on port 4000 simply like this and now we can save this and now since we are using an express application as we can see that app equal to express app so what we can do we can also use a middleware here for express so that apart from forward slash graphql because forward slash graphql is handled by this route here that is this apollo server but any other route should be handled by your express application so what we can do we can simply say app dot use simply like this and here we have the typical request response and next thing so request a response like this and i'm omitting the next here and here i am i can simply say rest.send hello from express apollo server simply like this so let's save this and now i'm going to open my terminal here and i'm simply going to start the server by doing npm run div like this and if everything goes well our server should be running on port 4000 and it is so let me minimize the terminal here and let's go to our browser here and now let me simply open a url here that is localhost port 4000 and we should be getting hello from express apollo server as we can see here and this is hand handled by the express application but if we go to this route here that is forward slash graphql we see that our playground has been initialized here and here we have the query so let me remove the query here and if we want to query the hello thing here which we created inside our type definitions and if we simply run it we see that we are getting back hello world so we see that our express server is also up and running and our graphql server is also up and running and it is listening on this route that is forward slash graphql and in cases if you want to change this path that is forward slash graphql so what you can do you can go to this middleware that apply middleware and here you can optionally provide in the path so let me provide in the path and let's say truly something like this and if we save this and if we go back and if we reload we should be getting hello from express apollo server because this is now handled by our express application and if we change it to truly then we should be getting our graphql playground simply like this so don't worry about this mutation here it is coming from another project which i am doing so just ignore this but we see that how do we change the path inside our apollo server express package so now let me go back and now let me remove this path because i want to keep it at default that is the graphql path now let me save this and now what i am going to do i am going to define these things that is type devs and resolvers in their own files so i am going to stop my server for a bit so let me stop the server and now let me clear the console here and now let me create two more files that is called resolvers.js and i am also going to create one more file that is called typedefs.js though we can use the gql extension but uh i am preferring here to use typedefs.js because it would be easier for you guys to understand that what i am doing and now i am also going to create one more folder here that is called models so touch not touch but it should be make the models like this and inside this models folder i would create a file called postmodel.js which would be a model for our post so touch models and it should be called post dot model dot js like this and now firstly let me finish up these on these things that is type devs and resolver so that our server.js file is clean so let me cut this type div from here so let me cut it out from here and let's go to type.js and let me paste it here and here i'll simply say module dot exports equal to typedef simply like this and now we are going to the server again and now let me cut this resolvers from here and now let's go to the resolver.js and let me paste it here and this should be called resolvers not resolver so let me change the file name here that is resolvers.js and here what i am going to do i am going to do the same thing that is module dot exports equal to resolvers simply like this so let's save it and let's save the server.js file and firstly what i want to do is that that i want to import the resolvers and type diffs into our server.js file so here at the very top i'll say const type divs equal to require we need to import it from typedefs and then we also need to import the resolvers resolvers equal to require dot resolvers simply like this so let's save this and if we start our server our app should be up and running because i guess i've done all the things correctly and we get an error here and it says that gql is not defined and it is pretty true because gql is imported here and not inside the type devs so let's go to the type devs here and here what i'll say cost gql equal to require apollo server express so if we save this the server should be running and if we go back to our server and if we reload the page and we need to change the url here that to the default url that is graphql and now if we make a query to this route that is or this query that it says hello we should be getting hello world back so now we have this so we have set up a server properly so now what i'm going to do i'm going to go to my post.model.js and here i'm going to create my post model so now let me minimize the server here or this terminal here and the first thing i would like to do here is that we need to import mongoose from august we'll say mongoose equal to require mongoose and now i'm going to create my post schema so i'll say const post schema equal to new mongoose dot schema and here what we can do we can pass in the properties which we want inside this post schema so this post schema should have a title like this and the type should be a string like this and it should be required and it should be true like this and now we need to define one more property of this post schema and that would be called description or let me keep it body here it would be or let me keep a description type would be again a string and a description may or may not be required so now these are the only two fields which i want to have inside the post schema and now we will create a model from this post schema so we will say const post equal to mongoose.model and here we need to pass in the model name or the collection name we want to save inside our database and that should be called post and it would be automatically pluralized and then we simply passed in the post schema like this and finally what we are going to do we are simply going to export this post from here that is like this so now let's save this okay so now before we can use this post model anywhere we need to make a connection to our mongodb using mongoose so for that let's go inside our server.js file once again and here what i'll do i'll require mongoose at the very top so equal to like require mongoose like this and then before listening for any event on this port 4000 what i would like to do i would like to make a connection using this mongoose thing so for this since we are inside an async function we can simply say await mongoose dot connect and here we need to pass in the url of our mongodb and here i am simply using mongodb on my local host and if you do not know how to run mongodb on a local host then you can watch my video that is linked above or otherwise you can simply pass here mongodb colon forward slash forward slash localhost port 27017 and forward slash database name we want to use so in our case let's call it post post underscore db something like this and then we need to pass in a couple of options because else it would give us some warning so we'll say use unified topology to be true and then use new url parser to be true simply like this and then what we can do we can make a log statement here that is console.log and here we can simply say mongoose connected simply like this so let's save this and in case this would throw an error then we would be getting the error inside our console but if this line of code that is on 22 line number executes then we are sure that mongoose has been connected so let's open a terminal here and we see that we are getting this message here that is mongoose connected and only after that we are listening on this port 4000 so now what we will do we will minimize this terminal here and we will go to our type definitions and here inside this query thing we will define our first query to get all the post so here what i'll do i'll simply say get all post simply like this and then what it will return it would return as an array of post or a list of post like this but to use this post here we need to create a type of post which this graphql should know that is inside the schema definition language we should define the type of host which we are using and if we open it side by side that is the postmodel.js here we see that here our post has two things that is the title and the description but in our case it would have one more field and that is the id of the post that is created whenever we save a new post inside our mongodb so for that let me define a type here so let's say type of post like this and it should have an id which would be an type of id again and then it has a title so we'll say title it's of type of a string and then it has a description which is again a type of a string simply like this and now we can use this post object that is a graphql object type inside this return here that is what to return when this endpoint or this query is called that is get all post so we are returning here in list of posts so now we can close this postmodel.js file and now let me save this and now if we go to our resolver for this resolver that is for this query we need to create a resolver so let me copy this get all post from here and let's go to our resolvers here and now inside this query i would define the resolver here like this that is get all post and this would be an arrow function again like this and we all know or if you don't know we can simply use async and await here because i want to avoid using promises here so firstly to get a list of all the posts what we need to have we need to have the post model here inside this resolver so firstly let me require it at the very top that is const post equal to require and here we need to go into the models folder and then we are going to keep uh go to this file that is post dot model simply like this and now what i'll say here i'll simply say const post equal to await post dot find simply like this to find all the post and then what we are going to return we are simply going to return this thing here that is this pose simply like this or to make it one liner what we can do we can simply return this thing here that is written like this and we can avoid this thing here because it will make our code much cleaner so now if we save this and if we go to our this graphql dashboard and if i reload the page here uh if i will write a query here that is get all posts like this and then why this is coming up so here what i want to get i want to get the name the id the title and the description of the post that is for all the posts so if we make a query and if everything goes well we see that we are getting back an empty array of posts and that is very true because we haven't created any post as of yet so why not let's jump into creating our first post so let's go back and let's go to our type diffs and here what i'll do i'll define a mutation type here because creating a post means mutation because we are writing something so we will say type would be mutation type like this and here what i'll do i'll simply create a mutation that is create post like this and then it would take in some arguments that is title would be of type of a string and then description this would be of type of string again simply like this and then what it returns it simply returns the post object that is created simply like this so here we have it like this but this is a little inconvenient so for this what we are going to do we are going to define our own input type that would be of type of post input so we will say input and it would be a post input so post input simply like this and then inside this what do we expect we expect a title would be which would be of type of a string and we also expect a description which would again be a type of string like this so instead of passing here title and description what we can do we can simply remove this thing from here and we can simply say post like this and then this would be of type of post input that we have just created simply like this so let's save this but now we need to create a resolver for this mutation so let's copy this create post from here and let's go to our resolver here and here this block of code is for the queries but for the mutations we'll create another block that would be called mutation like this and here we'll paste in that mutation that is create post simply like this and then we have a function here an arrow function like this and then inside this arrow function what all do we have we have the parent we have the context sorry the args not the context but now the context the third parameter is the context and then the info like this and now to get all the values which are coming here as parameters or inside the body of the call what we can do we can simply use restructuring here and we can say const title comma description equal to arcs simply like this and now what i am going to do i need to make this function as async because i am going to use await here because we are going to create a new post and we are going to save that inside mongodb so what i will do i simply make this function as async like this and now what i will do i'll simply create a new post like this that is called post equal to new post like this and here i can simply pass in the title in the description that is the title and the description like this and now what i'll do i'll simply say await post dot save not dave but save like this and then finally what we are going to return from here we are going to return this post that we have created that is the post that we have just saved so we are going to say return post simply like this not dot dot then so if we save this everything should work fine and if we go back to our this playground and if we reload the page here uh if we comment it out that is this query because we are going to need it in a moment after creating a post so what we'll do we'll say mutation and here we will say create post and then what it would expect it would expect a post and here we can pass in the title or here we can simply say this is first post and then we need to pass in the description and here we can simply say this is the description simply like this and now finally what all fields do we want to be returned we'll simply want the id we simply want the title that is the title that is created and the description simply like this so if we make a request so everything should go well but we see that here we have an error that is post validation field and path title is required so it is coming from mongoose but let's go back and let's see what's the problem here so what i see here is this that here we have a problem that is this title and description is not a part of the arcs but it is a part of args.post like this because insider type definitions when we create a post we define a post which is of type of post input and then that post has these fields that is title and description so inside our resolver it should be args dot post so if we save this and if you go back so this time if i make a this mutation again we should be getting our post back so let's click on this play button and we see that we get back the data that says create post and we have the id the title and the description and that is a mongoose id so if we comment it out that is this mutation and if we try to get all the posts that is to make a query again to get all the post again so we play we see that we are getting back an array of post so let's create one more post as of now so let's go here and let someone comment this mutation here and this time what i'll do i'll say this is the second post or let's simply call it second post like this and this is the description so let it be the description and now if i play we get back the second post and if we wanted to get back all the posts then we could can get it very easily by simply clicking here or getting all the post and now we have these two posts here so let me minimize the font size a bit little bit here so now we can see it all the post so now let's see one more thing that is how do we get a post by id because currently we have only this function or this query that says get all post but we also do want to get a post back with an id so we can do that very easily so it should be a query so we'll say get post and here what we'll do we'll simply create an async function like this and before writing any query we should firstly define the type definitions so let's copy this get post and let's go inside i type diffs and here we'll say get post not post but post and then it would take in an id of the post and this would be of type of id like this and then what it should return it should simply return the post here that is the graphql object type so now we can save this type diffs and now we can go to our resolvers here and here inside this function that is async function we again have the parent or we can simply call it underscore because we are not going to use the parent we are simply going to use the arcs and then underscore for the context and underscore for the info like this and now we can get the id very easily const id equal to arcs like this or we can directly use t structuring here as well we can simply say id like this and then we can simply omit it out so let me omit it out or let me simply delete it from here and now here what i'll do i'll simply say return await post dot find by id like this and here we can simply pass in the id that we have so if we save this and if we try to get this post or any post so we see that we have these two posts so let's try to get the second post so let's copy it from here and now inside this query let me comment it out and let me try to get a post here so this won't auto complete until and unless i refresh it so we have a error here or a problems let's see our terminal so what's the problem here so the problem is something like this that is duplicate parameter not allowed so what we can do we can call it like underscore parent and then this would be underscore context and then this would be info simply like this and this should be up and running now so now everything seems to be fine so let's go back and let's reload the page so now here what we can do we can simply say get post and here we can provide in the id and we can paste in the id here that we just copied about a moment ago like this and what do we want to return here we simply want the title and we want the description here so if we run this query we should be getting the post here that is with the title and description and that is very true because it was the second post so now we see that how do we create a post how do we get a post by id how do we get all the post so now let's see in that how do we delete a post so let's go back and here firstly we need to go to our type devs and here inside the mutation we'll define the delete post mutation so we'll say delete post and here what it would take it would take in the id to be deleted like this and then what it would return it would simply return a string in my case though you can return whatever you want to return here i am simply providing a string that says ok that means the post is deleted so we can save our typed diff we can copy this delete post from here we can go to our resolvers here and now inside the mutation what we are going to do we are going to define this function that is delete post and again it would take in the parent the arcs the context and the info like this and then again i am going to make this function as async and then this should be equal to an arrow function and there is a problem with this async spelling so now it is fixed and here what we'll do we'll simply get the id like this that is const id equal to arcs simply like this and here what we'll do we'll simply say uh await post dot find by id and delete we will say find by id and delete and here we can pass in the id here and then what we can return here we can simply return here that is okay post deleted or whatever you want to return back or whatever message you want to send back to the client so if we save this everything should work fine so let's go back so firstly let me try to get all the post and we can also get this post with an id here it doesn't matter we can get both the queries in one go so we have the second post and we have these two posts so let's try to delete the second post so let's copy it and let's go back no we do not need to go back we can comment out this query and what we can do we can go to our mutation here and we can uncomment it and instead of creating a post let me and comment it out and here we will say delete post and here we need to provide an id and i'm going to provide an id of the second post and then what do we expect back we simply expect back our return next string back so we do not need to provide that and if we click on play here we see that we get this message that is ok post deleted so now let me comment this mutation out from here so let's scroll up and let's make a query again to get all the post and this time let me comment it out that is get post and if you make a query to get all the post we should be only getting a single post that is the first post because the second post has been deleted so now we know how to create a post how to delete a post how to get all the posts how to get a post by id and now one thing is left and that is how to update a post so let's go back and now let's go to our type devs and here we will define one more mutation and that would say update post like this and then what it would expect it would expect a post type which would be of type of post input like this and then what it would return it would should return the updated post like this now let's save this so now let's copy the update post uh mutation here and let's go to our resolvers here and now inside the mutation we can define that function that is update post again it would be an async function and then it would have the parent context and info like this and then what we can do we can simply say const title comma description would be equal to arcs dot post but the problem here is this that we do not need that which id to update so for that we need to somehow modify our type definition so let us go back to our type definitions and here before requiring this post as an input here what we can say we also want the id that needs to be updated so we can define it like this that is we want to update the post with this id and then with these fields that is the title and description that are the updated fields so now this makes much more sense and now if we go back inside the resolver again we can get the id from the arcs we can say const id equal to arcs like this because as we know from the create post thing that is args.post contain the title under description and inside the arcs we have the id because inside our type definitions the id is provided like this so now what we can do we can simply go here and here we can simply say const post equal to await post dot find by id and update so we are going to use this function here and here we need to provide in the id and then we need to provide in the fields that we want to update so we can provide in the title and we can provide in the description like this and then we can provide in a second parameter or the third parameter here that is to return the new document that has been saved so we can simply say new to be true to return the new document that has been saved to the database so let's save this and then what we can do we can simply return this post from here because that is the type of return we want from our type definitions as we see here that is here we designed for post that is here we have defined post so we are returning a post here so now let's save this and if everything goes well we should be updating our post in a moment so we have this post with this id so let's copy this id from here and let's comment out this query from here and let's scroll down and let me uncomment out this mutation because it's a mutation and let me comment out this delete post from here and here at the very top what i'll do i'll write my mutation for update post i'll say update post here we need to provide in the id so id we are providing in this id and here what do we want to update we want to update the post object like this and here we can provide the title and the title should say so new title simply like this and we can provide in the description and we can simply say new description simply like this and what do we want to return here we want to return here the id we want to return here the title and we want to return here the description so if we click on play we should be getting the updated post and if we comment out this mutation as an hole and here if we try to get all the post then we should be getting only the updated post that is new title and new description so now let me show you one more thing that is if i comment out this query and if i uncomment this mutation from here and it is for a reason i am showing you this and now let's see i do not want to update that description here i only want to update the new title so let me remove this description from here and i am only posting a title here so here what i can say i can say first post title like this and if you click on play we see that we are getting description as null so this is something you should know about that is if you update like this then you should be passing in null here so what you can do you can go back here and here before updating the post what you can do we can simply create an updates object here that is const updates equal to like this and then what we can do we can check if not or if title is not equal to undefined then we want to say updates dot title equal to title like this and then we can again check that as if description is not equal to undefined then we can say updates dot description equal to description simply like this and then instead of passing here the title and the description like this what we can do we can simply pass in the updates object here we can simply pass in updates here like this so if we save this and if we go back so right now we do not have a description so let me provide in a description here and here i can simply say new disk like this so if we paste it we see that we are getting the description here but now if we omit this description and we only want to update this title so let's say new first post title so then we should see that this description would be posted inside our database so if we click on play we see now we are getting this thing here that is new first post title so guys i guess that this is all about this video so now you know how to create a post how to update a post how to delete a post how to read a post how to read all the post so that's all about this video so if you like the video do hit the like button if you haven't subscribed to the channel do subscribe to my channel so thank you bye tata take care and have a good day and have a great day
Info
Channel: yoursTRULY
Views: 10,322
Rating: undefined out of 5
Keywords: What is graphql, Graphql tutorial, Easy way to learn graphql, Graph-ql tutorial, What is graph-ql, Getting started with graphql, Apollo graphql server, Crud operations in graphql, Query and mutation in graphql, Yourstruly, how to create an api using graphql, how to use express with Apollo graphql server, how to use mongodb with graphql, how to create a Apollo server for graphql
Id: xUQ-hNRHCgs
Channel Id: undefined
Length: 36min 56sec (2216 seconds)
Published: Fri Apr 16 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.