GraphQL API With Express, MongoDB, and JWT

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone in this video tutorial we are going to create a graphql api for a blog site graphql is an awesome piece of technology that gives power to the clients to choose to fetch what data they exactly need this wires over fetching or under fetching data to give a small demo of what we are going to build in this project so even though the posts author and comments are living in separate table or separate resources separate databases graphql allows the client the front end to to query everything together in one go so that's the magic this is a completely uh a back-end code with no front-end involved we are going to start from setting up the express server and making the graphql work with it and we're going to use mongodb for storing the data um we're going to use jwt for authentication or authorization let's get started section one in this section we are going to install all the required packages and we are going to create um the express application web application and we are going to configure env so i i have open vs code here and i'm going to drag an empty folder i'm going to use integrated terminal okay so this is the package we drag a folder we drag it to the vs code let's initiate the node package so this command creates a package.json file with all the default values set up this is fine for now so this package.json file will keep track of um all the dependencies and dev dependencies on the metadata about the projects of node project let's go ahead and install the required packages we are going to use express so this is the web framework we are going to use on the top of the node.js is much friendlier that uh to create a web application using express compared to the node.js we need graphql so this is this npm package is actually implementation of the graphql runtime in javascript so we need that express graphql is a graphql middleware http middleware which makes these two packages work together and we would need dot env to store and retrieve environment variables we'll save a bit and we need the json web token for authentication so we are going to sign and verify jwts using this package it's going to be much simpler um authentication system you're going to have in this project using json web token you need the mongoose package so this is this is an odm this one which basically maps the object we create in this project versus the actual document in the mongodb is just an object document mapper so that okay so these are six uh dependencies we need for this project while it is running we also need a depth dependency so that is uh noted by this hyphen d that's an that's a package called nodemon which uh which actually reloads the server whenever we update the scripts here so which which saves a lot of time in the development okay the installations are done i like saving my main file as server.js okay so as the installations are done we're going to let's go ahead and create our server [Music] and let's have a sample root route which basically returns a json message hello and let's listen to our route of 3000 okay so that's all it takes to create a express server let's create a script and run move on server.js start okay so it says app is app running on port 3000 let's go and check that and it says message hello world so this is the message we returned here so the express server is actually work is working and i wanted to configure dot env let's make this port number come from an environment variable port 3000 and we need to configure that in order to configure we need to import that and config so if we choose to have this env file somewhere inside the folder then we need to configure the path inside this we don't need that right now and once we once we have configured this no dnb package will basically load these properties and then we can be filed into process dot e and b dot port so we can access the environment variables inside this object here we'll also update this so we are seeing this 3000 this 3000 is coming from the process of enviro i think the font is bit is small okay okay so this the port the 3000 now we can access uh inside the process.env so we have our so section one is done so we installed the express install all the packages required we created the express application and we also configured our tnb so let's see in the section two so before proceeding let's initialize a get get repository so you just get in it i've already done it and we need to add dot key take note we're going to ignore the enemy file and then the node modules [Music] so they are gone so these are the things we did so we installed the packages six packages six dependencies and one dev dependency and we created a express server let's go ahead and commit the initial commit in this section we need we need to configure mongodb we are going to create a mongodb cluster in atlas just google atlas and click the side and sign in i have already signed in here so click on create a cluster aws is fine and create cluster these are the default configuration for a free frame rate cluster these guys don't even ask any credit card or anything so it says new classes take between three minutes to provision but it may take up to five or five to ten minutes see again so the cluster creation was ready if it was running too too long for you just refresh the page you just make sure that you have the red green dot here and we're going to connect we need we just need a connection uri and then we may even forget this interface we can just deal with the collections and everything right from our project so you can click this uh it just allows the correct current ip address we need to rightly sum ip address in order to access this cluster i'm going to click this so this makes allows anybody to connect this is not safe but just for the tutorial i'm doing this you can do this option and you have to create a username anything is fine for the tutorial the keep something safe for important databases i'm giving the same i'm going to delete this cluster after this tutorial we database user change your password sure so choose a connection method we're going to connect with our application so we are using node.js and just copy this so this is the uri we will deal with the whole thing we will we need to update this password to what we gave the last screen we can give any database name here so copy this okay so now we got the mongodb uri the database uri from the marguerite backlash so we save that in the dot env file let's go ahead and test the connection so mongoose provides us a function called connect which gets the uri so this one i'm going to pass this function exposures export this function as a non-default one need to just import the function and then call that that's all let's see if it works okay it's not running oh something went wrong and i will promise you the url there must be a string but current defect uh okay so actually what happened here is that we call this function before even configuring the dot env yeah so the mongodb is connected now but these are some warnings we can add these options here to get rid of there's one more thing okay so we have connected to mongodb without warnings let's go ahead and create our models our browser comprises of three models user post comment so this mongooster schema function so already we use this mongoose.connect this is the second function we are using from mongoose which is schema which gets say if we see the hint it asks for a schema definition and schema options so let's just see the schema first we need the username which is a string and password password email display name and we use mongoose. we need to export the model give it a name model ask for a string as the first parameter and then the actual schema we created so this is actually a valid mongoose model we can go ahead and actually create user collection with the documents with all these um properties but we need to add i wanted to show this um as a bad skeleton of for every model but we want some validations and everything so instead of just giving the type we can have we can actually have same energy javascript object which carries [Music] some the validations etc so here we need the username whenever a user tries to create an user object we use a document in the data and the mongodb is mongoose this model restricts if the username is missing same goes for the password also the type string is obviously password is required and also we need to have select as false this is select property make sure that while retrieving the the user document the the document won't contain the password in this project we are not going to encrypt the password um but even though if we encrypt we don't need when whenever the user whenever anyone reads retrieves documents we don't need the password so we select pulse make sure make sure it won't return it is required and also it should be unique and we are also going to use regex validation here which i copied from stacker overflow this match gets two values it's an array it gets two values manipulate x second one is the error message if there gets fails please under a valley email who makes the display name let's just type string which is also required okay you don't need terminal open all the time so the shortcut for you opening and closing the terminal integrated terminal is control and tilde okay so the schema as we discussed it gets the schema definition first as a first object first parameter and the schema option so i'm going to pass a schema option called timestamps so this this options make sure that this document will will um keep track of which basically includes additional properties called created and updated which is very helpful you know the document gets updated it keeps track of the time um okay let's get all the models i prefer typing instead of copy pasting that gives some muscle memory maybe i will fast four schemas done another comment okay so now we have our three models ready the user schema has user a password display name and email with the validations the image will be unique for each user and then we have we also have like x validation going on the post has the author id who wrote the post um with a title and body so we are not going to use the name uh what you see is what you get editor or basically the rich text support we are we are not going to store html we are just going to store a string for a title and a string for a body for this example we also have time stamps enabled here and we are exporting that this mongoose model and for comment we have actual this is actually commenter text and then the who who wrote the comment and who um the post id of the comment we also have timestamps when we export it and we will have another file to export all from one place you said it's user okay so that's all for section two um so we have connected the database and we created three models using uh starting from the user post comment we exported them from one place and in the next section we will continue with um creating the graphql schema queries mutations types let's see in this in the next section in this section we're going to make the graphql work with express we're going to create the basic the liquid files and then a skeleton schema file and we're going to just make make them work together before jumping into creating the queries and the types queries and mutations we're going to just establish this connection mutation queries types in the schema so let's start with the schema schema makes use of the actual graph cable npm package so okay the skeleton of schema and schema is import required stuff from graphql first step import queries and import mutations we are going to define the queries and mutations inside this queries and mutations and define [Music] query type we're going to input all the queries defined inside this file and we're going to combine them into one whole query type same goes for mutation to mutation type which carries all the mutations we have declared and modulo exports we are going to export graphql schema okay let's go one by one right now we don't have any so we don't we are not importing anything and that a query type is let's see the query type is a graphql object type just like how we install uh fql schema the query type is graphql object so as you can see if you have this setup ready like this it will keep populating as we as we use in the script that's very helpful we don't have to do it separately so any graphql object type takes a name first let's give query type and a description um queries and fields which is going to be empty for now we are going to import all the queries here and then we are going to just feed them inside let's do the same for the mutation type okay yeah right so we have created the query type and mutation type we need to export them inside wrap inside this graphql schema so the skeleton schema required for a graphql is ready now ready now now we need to feed the graphql inside our server file let's and for that we need the graphql express graphql we're going to use the on graphql http let's use uh so the graphql is going to exist inside this route graphql and and instead of passing a a request response function like this we are going to use let's grab qlize to tp so the graphql http gets the schema and the first one is the schema and then the second okay this is a es6 syntax we can do this graphical the second one is graphical true this enables us to um this is actually an interface which is very helpless okay everything is working let's check that maybe let's change this message a bit like something welcome go to slash graphql and let's go to graphql okay message tag expected token in json position zero syntax of the next operand version zero in fact i was expecting some actually a different error here saying that the fields are feels or empty but it's saying something else okay um let's try using use here i think it is trying get get some html or something that's what i can think of when i see this yeah oh what is sorry terrible mistake i updated this gate okay let's use this use here yeah so now we get the expected error which is type query type must define one arm more field square mutation type must define one of the fields actually the express graphql site if we see right then the npm it asks us to use get our post so this is the function we are looking at post somewhere i say okay i'll say use get.get.post rather than use to configure route handler if you want to show graphic element set graphical tool on your git handler but um i did this right i restarted with the dot get handler but we got that error the tag missing or something okay let's just go with this use the use is this is basically i think it works the same way as get or pose but whenever we use use we are we use a middleware so this basically looks like a middleware to me with a router so as this gate didn't work we're going with the use that's all right okay as you can see the section three we made graphql work with x with express just to summarize what changes we have done we started with creating these files mutation queries schema and types and we created a skeleton schema required to run this from graphql import a good stuff from the graph here regular queries you can import record mutations from mutation mutations is it still working yeah fine mutations and we defined a query type using graphql object type and we defined a mutation type with the same thing and we exported this both wrapped around a graphql schema in the server the server the differences the changes we have made as we imported graphq we imported graphical http from the express graph cable and and the schema and we use this middleware to route to graphql this graphql true this option allows us to access this interface if we if we take this out we won't be able to access this must provide a query string so this this works like actually hitting the actual api so it won't give us the the playground graphql playground if we not enable this option and also you can do this it still works and let's go ahead and commit in this section we are going to create types let's establish the skeleton so a type in graphql is a model in mongoose we are actually going to create these three types here let's also import the models user post comment okay let's create the first type which is the user type the user type is again we are going to make use of the graphql object type this one and it as we know it takes name description and fields user description what user type and fails right now we are using a function which returns and json object a javascript object we will talk about that um here we saw that fields are just an object but here we are using a function to get this we'll talk about that so it will have an id this id we did not have in the in this model let's just keep the user model open so we just have username password emails and everything but not the id but when we create a document in the mongodb it's going to create an id for us so this is that id next one is username and i'm going to use password here because we don't have to retrieve password we get from when the user creates that account and we when he logs in whenever we deal with authentication and authentication we actually going to use express middleware as an express middleware using json web token or the graphql is no thing won't do anything with authentication so these three guys are actually going to be graphql string type so the user type is ready now when we move on to the post type there is a small twist which is again the same graphql object type which gets the necessary fields and on the field we are going to use a function returning edges javascript object let's do so it is same till this point but this is the turning part of the project of this video where we are going to see why we are we have to use graphql in the first place a graph a graph basically connects the nodes it makes relevant data together it keeps relevant data together right so a post type for a post the author and the comments or relevant types so we create this author and we start with the type as we have done above but we are going to have a resolver here resolve is a function for the first two parameters are going to be parent and orgs and it's going to return the author is going to return user dot find so this is the first time we are going to actually hit mongodb parent.id the parent oh sorry parent dot let's open the poster this this document this is a representation of the mongodb document and this document has author id so that's what we are going to access from here the parent is actually a documentary document and we are accessing the author id from the document we use the author id to query the user this may look a bit weird but this is what we are going to do again and again whenever uh whenever we talk about this keeping relevant stuff together we are going to do this again and again in fact we need to do this for the comments comments is actually a bit different the oh actually so okay actually the um okay the id is going to be an id the title is going to be a string the body is going to be a string but author i did a mistake here that it's not actually a string it's actually this user type right okay because yeah so it's not going to be a string it's going to be this document again with the with id username email and display same goes with the comments now you will we will see why we are using a function returning this stuff instead of the actual uh instead of just a so maybe i'm confusing a bit but hold on to me now in this part in this comments we need to give the type as common type which we haven't created so when the javascript engine reads this line by line when we come to this part and we just if we just give comment type it's going to throw an error saying comment type is not even though if we have a common type here calcula object type as i said we keep doing this stuff again and again whenever we deal with the graphql comment types types [Music] type and then we are going to have the fields which is again a functional returning adjacent object yeah javascript object so this is like this comment type for an engine when if it just have this as a javascript object when the engine keep uh reached down line way line when it reaches this point it's going to throw an error if you have a function it won't because it just remembers the field as a function and a function the stuff inside this function happens in the execution time so when it executes the command type will have been defined so that is the point we will see this in when this executes i'll change this into a object it's going to throw an error in the schema which is not the case because we everything we are going to feed inside are already there defined so that's not going to throw an error i think that's clear if not just hold on we'll see that in in action so the author is just an user user type is a document but the comments is actually in an array so in order to use an array we are going to use like calculate graphql list i got to pass it's a list of this type and we're done with the post type let's move on to the comment type this resolve function comes with lot more parameter also like a context stuff comes after this we use that for authentication for now we are going to use only the parent and orgs the arguments i think we are not using arguments um uh okay so let's talk about these parameters for a bit the parent parameter points to the actual post document in the mongodb the actual document the object which comprises of all these fields id title author author id this stuff as we discussed and the result inside this result it allows access to the actual parent document and the arguments the arguments we will use in the mutation when we try to query a particular user with an id or something so in there we'll use arguments and the context it comes after this we will use in the authentication so for comment we need to like um relate the user and then the post for resolve we are going to use the post so we have imported all these three uh models as you can see we are not we have we created these models we connected the mongodb and then we just use these guys as the broker we forget about all the connection and everything we just use them and talk with them we don't we forget about everything else the connection and that abstracts a lot of complexity so this is user okay user model dot find by id and we're going to pass the parent dot user id so this parent this user this is exactly this is the property we are when we are using here and and the comment will come with the post parent.this parent.post id this one it has to be same whatever we have declared here we have defined here should be given here because that's how we are saving in the actual document in mongodb i okay i think the types are done let's export them comment are you not using commenter post comment okay here i made a mistake i should have given comment and it's not find variety but right just fine this accepts um the id and and it returns one document but to find we are going to actually give a poster this is like a bad condition in the in sql find where post id is equal to parent or id whatever this id is is going to query all the comments for this post we are not doing page nation yet but we but this will work for this project i think that's all so in this section we talked about the types type what is the type in a graphql and we talked about the resolve how this resolve connects the relevant data together and that's it let's go and commit testing let's see in the next section in this section we are going to take an aside and we are going to see how to do authentication using jwt okay so we need to create a utility folder here we are going to create a function which which receives a user object so we're going to use this function exposed by the jwt package to in order to sign a jwt token yeah json web token so sign gets three parameters first one is the payload we are going to pass the user object as a payload second one is a secret key secret or private key we will have it here and we will move that to the x environment variable the third one is options where we need the expires in options we are going to pass through it 30 days inside it this format is called a zms let's let's see that so this is the expire these are the options we can pass inside this third parameter algorithm we can change algorithm we're going to miss high choose 256. okay we are passing an expires in and we may even choose to pass bit not before so that the token will be not valid before some certain period we don't want any of this right now i'm going to show this times uh the the format of this so you are using this format this 1d or 30d is also valid we can mention a uh experience for a token in hours also so it provides lots of um ways to do this create okay so i'm going to actually create created this route here in order to test just this one route which is called auth test we can give any name here here i'm going to import that you click that create jwt method a function and then so from this route we are just going to return back this thing so we just we just created this function here it receives an object anything can be anything it doesn't we are not doing anything here with any validation it doesn't matter right now and the sign it gets the payload it gets a secret and it gets experience as a part of option it creates it's a synchronous operations because there's no await or anything it creates the token it returns back and for testing that we are we are accessing the function from a test route which is a gate we are going to hit this from the browser and what i'm going to do is we're going to pass the user object this user object where i'm going to just hard code it okay let's start so you're going to do we don't have to do anything from here all right i was doing some testing here when we go to this route it's going to give back us a long string this is a json web token and what happened is i hit this i did not send anything i could have used postman or anything to attach a body but in order to make it simple i'm just hard coding and user object here the request hit this endpoint this endpoint asked help he just called this create json web token jw token uh i think it's not grammatically correct or anything i don't know technically json with token token okay whatever please bear with that we are going to we are passing a user object here it went here it cooked a token here and returned back and and yeah the response basically returned to json that's why we ended up here with a token so open go to this site jwt dot io so this is the stuff we passed it also added the issued date and expiration date as you can see so it is issued at september 12 and the experience is october 12th because we gave the expiry data 30 days um and yeah so one more important thing so how is it is this going to be a secure thing it is not a secure thing it's just encoded if we choose to pass for example if we are going to just pass an unencrypted password that is vulnerable as you can also see that when i when i increase the payload size the token size gets increased so this is the this just encoded is not encrypted the sign is not encrypting or anything it's just encoding so the data we put the pillar we put inside can be decoded anywhere if the the person gets hold of the jwt and how is this secure for what we are using this and good example is that if we have our payload which says admin false the user can or the attacker can actually see the message here but if he tries to change this to true it actually gives back a token right but it's not a valid token how do we know it's not a valid token we are going i said it it takes it it has two parts in our authentication one we are actually signing a token and another we are going to create a middleware where we are going to verify the token and there it will fail whenever the the hacker the attacker or the user mischievous user tries to modify this payload we are the dwt is going to throw an error so let's see that for that we need we're going to use middleware rec dot headers dot authorization so this is the header we are going to attach or the server is going to expect the user to attach um [Music] so the standard is to actually use something like so this is what we are going to hit i am actually using a chrome extension called mod header authorization bearer space this token whatever it it's written but we are going to store this in the local storage and we are going to send that in every request as authorization we will see that after finishing this method function right we're going to split that so what happens here is that this is you know option chaining option training in js which is available in node 14 and above just make sure you have 14 and above the 14 is if you don't have a fourteen another go to the site and install the latest one this current with latest features i think uh the 14 gets to the long term support this october active lts starts so the version 14 will become lts this october 27th so go ahead and install this version so that this will work the option training or else we need to use something like if um record headers available and then record headers dot authorization available ended so this and chain this actually typescript introduced long back and then now javascript is catching up verify equal to we are going to use the jwt so this is the second function we are going to use from the jwt first one is the sign it took three three three parameters the verify takes the first one is the string the actual token which we get from the client which in the first place we sent sent when he registered or logged in and the second one is the secret the same secret we passed in here we're going to send that here okay so before touching this part let's take this stuff and put it inside our environment for uh files 30 days okay jwt secret i hope it should work fine let's move on so we got the token it's just we are just doing some string manipulation here here we are getting the authorization and splitting that taking the second uh element if there is nothing we are going to at least pass an empty string or the verify is going to throw an error so the first one is token second one is dot env dot jwt secret that's going to verify so what we're going to do is we are going to add an object to the request so that everybody uh every route can actually have they can access the user let's just had this verified with the verified object okay so what we're going to do is in the server we're going to use before every every route we're going to have a middleware so that we need to also import import that earth middleware which was authenticate and we're going to just pass that like this okay um okay from inside we need to call the next one or else the action is going to be just it's going to end here so the request every request comes to the script it reads line by line it comes here it yeah we have added a middleware right so it's going to go to this authenticate function it's going to do this stuff and we are actually attaching something in the request also and here if we access it's going to maybe let's just log request dot verified user that should work actually so that's the whole part of having a middleware let's see how jwt protects information or the authenticates the user for example so this is the data we sent back to the user we the one great thing about uwt is we can have this vital information like display name email sentiment with every request so they can always take the information from from the token itself when the user tries to when the user if he tries to modify this data he needs a secret key to to verify the signature and he may just guess it and if we copy this if we pass this that's going to say verification failed so the request came here we um took the token we tried we verified it and it actually went wrong let's also try to have the error printed here which says invalid signature so the attacker cannot change the data even though the data is available and we should not keep sensitive information in jwt the information we sent back to and fro from the client from the server cannot be changed if it changes when we verify we are going to catch that if somebody um did some malfunction and one big catch is that gwt unfortunately has a similar method called decode now you know that the usage or admin i just updated this i'm going to change this updated this and i just verify the signature using some random secret i'm going to send this previously it failed now it says verification success this is actually a problem we should make sure that as a developer we may we may we may there is a chance that we may miss this that yeah okay so i get the token i verify that and it's working fine so we may just go on move on from this but there are two functions on this decoder one is verify the d code that's exactly what this this site is doing it's just the codes it's just decoding the token and getting the data from it so we have to make sure that you should use this one you should use this one we should use the verify not decode the d code is going to always decode no matter what it's not it won't verify the signature um i think that's all about the authentication in the next section we will go create the we start from the register login and we will use this two functions in the upcoming mutations so to summarize we created this one we use this function from the jwt sign and we are signing a token here and then we used the verify to verify the token be the client sends back and we also saw that there is one more similar method which is dangerous to use um don't use this and we created a dummy route to just test this we are going to just discard these changes from this file we don't need this and let's commit it let's say in the next section in this section we are going to do mutations so we have imported the required stuff so when we start using the the exports this guy the exports will get populated here automatically let's let's go with the register ql string so when he registers we are going to send back him the string arguments you can just give this graphql string and email password display name so everything are just strings and the third one is an async resolve which gets the parent resolve parent and arcs these args are basically this this ones we get from the request so you want to create a new user before the review you can destructure username email password display name from orcs and will pass the same into this user list the mongoose user model we're creating this save so we save that and we need to have the utility function now slash auth it's called create there will be token and we're going to create a token here equal to of user so okay we created a we are getting these arguments we are using these arguments to create a new user this user.c will actually go ahead and create a document in the mongodb atlas we're going to return back by stringifying the token actually um graphql is very has with stick types we can choose to actually have a another type here called a token type which we can pass but i'm let's just go with the graphql string we are good with the register now let's explore that okay so now we are going back here and doing this so it's working it's it's running let's grab cable message query type input type got undefined username that's your type input type okay so this must be inside an object is that so yeah so we'll do this for everybody so it still needs a query to show us the schema so let's i did not want to come here before doing these mutations but um i could i couldn't show the documentation here so for the sake of seeing the documentation let's go ahead and create the most basic query for that also we need these setups again as we saw here we need the types models and graphql okay let's get the most basic one users this will look very familiar new graphql list we used this while creating the comment type in in the post right the graphql list which is a list of comment type which is of user type so here this is a list of user type the user type we get from the uses resolve will carry the parent as the first eye parameter and arcs on this as a second one we're going to return by saying user dot find that's all so this will bring all the so this is a valid query it has a type which is a list of a user type and in the resolve it just returns back all the uses so we created one mutation and one query so we can import the uses from the queries and add it here so now the graphical shouldn't complain so yeah so it's not complaining we have query type the documentation is a great as a convenient part in graph graphql the consumer of this api graphical api can go ahead and see what to expect so the mutation type the register asks for this particular properties using an email password display name and it just returns a string let's create our first user okay it says the payload has to be a plain object so basically it's not accepting this users and as a plane object so this is basically a mongoose document or so let's see so this is the first argument is the payload let's just wrap that inside another object this is the shortcut of this duplicate key error collection okay so what happened is that this problem is solved now so when we previously tried it created a document with the same email id and the same if the humanity is unique needs to be unique right so it created the document and it failed in this part by creating a token so what i'm going to do is um i'm going to go ahead and delete that in my mongodb atlas so we already have the j2 melody here so i'm going to drop we can actually drop the whole collection whole collection because we did not create this in the first place right so when then we we try to create a document through mongoose here it looks for the table name and if it's not there it's going to collection sorry if you look for the collection name and if it's not there it will create it so let's go ahead and try it once again okay so we got the token back but there is one problem that we don't need is slashes okay so we are unnecessarily stringifying this create jwd token this function is actually returning a string so this is not necessary i'll go ahead and delete that fire also candle this whole thing it will get created if it's not there let's try again zero okay okay so now we have this data beauty ready jwt dot io okay so this is exactly our document here so this outer braces is what we we have given here so we try to give this part but it did not accept that as suggests a javascript plain object so we've wrapped everything inside another another object and it's working now it's good we have created one john doe document let's try let's create a login mutation and try to login so this is exactly the same like the previous one you're going to return a string the arguments are going to be um email and password well both are going to be strings the resolve method first let's try to um access if there is any user available with that email id this is like a bad condition in sql so we get the user and the user first user has to be there if there is no account associated with the email given email id this object is going to be null and one more thing is that the the password he has given here in the past in the arguments and the password we have stored for the user inside the user document must match the org start password not equal to equal to use that password so if any of these conditions fail we are going to throw an error and we are going to generate the token as above token is equal to create uwt token we're going to pass the user and return the token that's all for login let's pass it here as you can see the schema as we have already created this schema printer that's the skeleton of the schema already it's easy to add new functionality to the project right yeah so with now the login is ready and our mongodb is connected you are getting some other deprecation warning also you will see it whatever okay now the documentation should show the login location type now we have the login also let's try to log in with the same um credentials login email password 2345 okay so first try let's try with um the email which is not there so it gives invalid credentials because yeah there is no email and associated email for any of the documents and the user is null so we through this error in my credentials let's take this fix this and yeah let's give some other password it is the same and if we give the correct email id and password it's going to wow one two three five john doe gmail okay is that anybody okay so we are not including the password here you remember we uh in the post document we have given like select false which is still necessary we don't want the password to be returned but for this particular uh for this action we need to actually include the password for that we need to can actually change this select and they have to pass to we have to ask to add the password to it okay still okay we have the password this is same okay see okay okay i did it there will mistake here it has to be fine one the find actually returns the whole array so it looks for user.password but actually user is an array of this mongoose objects the find one should return one object so that we can access this user.password yeah okay so the now the login is successful and we have got uh token and we have all the information inside it required so the login is done so in this section we have we have added uh the register and login mutation and we have our first query okay maybe let's go ahead and try this uses so right now we have only one user and let's let's query that query users id username this display email i think that's all yeah okay so in this section we have successfully have created our our first query which is basic which is that's all with 12 lines of code and then we have two mutations one for registration and one for login and we imported this thing we had this stuff ready uh with this empty curly braces we just we can import any number of queries and mutations and we can just keep operating them and we updated this one because it didn't work it didn't accept the mongoose object as the plain javascript object in this section we are going to create queries and mutations for the post type so before that in the last section we forgot to create the query to retrieve one user i'm going to use find by id robust the arks dot id you can also have description here that's helpful in the documentation okay so now we have two kinds of queries users and user and we have description also here let's try the use the user query ids this one okay so the user query is working so before moving on to the po to the to for to create posts and mutations for the post type queries and mutations for the post type we need to make sure that only the authenticated the logged in users are allowed to post to create new post so for that we already have this middleware ready we are going to import that and let's call authenticate and we need to have this before all these routes so this function receives the request it gets the token it verifies it it attaches a property the whole user object as a property to the request so that allows us to use so in these routes in the query in the mutations we are going to look for this verified user property in the request if it's not there then it's he is not logged in let's create that post mutation which is of type post type previously we just we were just returning the string and we're going to get the arguments title which is a graphql string and a body graph your string and our result method will be having the parent works and here we can this is the the order of the parameters are important um the first one is always the parent the post if we if we log this parent it's going to lock the post document the arguments are these guys which we received in the mutation the third one is the context um [Music] so the the authenticate function when it runs if it touches the verified user we can access that from the context the third object if there is no verified user we're going to throw new error if it's not we are going to go ahead and create a new post it's going to work like how we did the registration here we're going to just pass the arguments inside author id title is arcstar title body srs dot body i'm going to return the post dot save so that's a promise and this should work before creating the post we need to login so we have only one user here let's log in with this with this credentials so this is the jwt and i'm using a chrome extension called chrome mod header so install it but you have to make sure that you once you you you're done developing authorization space this token since you are done with this development uh if you still have this mod header with this authorization or anything that's going to screw up with uh with some sites when you visit because it is it is basically there in every request so make sure after development you come here and even disable the extension so we have our jwt we copied that we we put that inside authorization let's do it let's create our post okay post validation okay something went wrong folks validation fail authority is required okay so this authority is not coming here okay so um okay so we have wrapped this user inside an object so when we try to access like verified user dot this id we are getting an error so actually it's like it's the id is living inside and user object okay so instead of doing here do it in the middle there okay so here we are saying that and we are saying this one let's try it once again and this won't affect uh this won't create any new documents here because the validation stopped the document from getting getting created we don't have a post collection here yet it's running let's try again okay so document is here so b9e so he is the user we logged in with and b9e and that is the author id and the good part is we did not get this input from the client but the jwt which was created by the server so it is secure a lot secure than relying upon the client okay so now we have the add boost let's go ahead and create on the queries just like how we did the user and post is going to be pretty similar post equal list of post type and let's have a description also retrieves list of posts and a result function we don't need actually we can skip the arguments on the parent of the arguments post dot file let's do the same for post the type explain type id is going to return only one post and we need to pass the id as parameter and resolve we need to have the arguments actually we can we can uh name anything here instead of parents we can if we are not using that we can even put a dash here but the order is important i think we are good so once we have this setup it's you can see it's very it's very simple to keep creating queries and mutations let's retry so that we can see the updated documentation here queries we are not seeing the post one hmm that's strange this is list of posts the schema will happen post post okay i think i entered the post two times okay so now comes the big reveal we are going to look at the posts oh okay query post um can import the i can see the id title body and the the documentation helps here a lot right the post which gives us all this stuff or the author comments we haven't created any but this is the magical part these two stuff the author and we can just keep going inside id so we set up this in the type in this type we have a resolve method for the author which connects the um the i the user the user that the the user data into the into the post what do we have in my display name for example we usually don't need the email but we may need to display the display name along with the post yeah it's great right let's also quickly test the post so this is not possible in a in a normal rest api if we want to com combine two resources we can do it in one api one endpoint but that is fixed if you want a different response we need we need to have different apis or that's going to be messy we can have like conditions what to return back but now this is the front end and the the front end decides what information it needs if it needs an email id an email id again for some reason it can have so whatever data we have we can do it we can have our authorization back i i think i i i cannot uh cover that in this video but let's see we'll do a bit of authorization using this jwt while while updating the post so who can update a post only this guy can update the position john doe can update the post so we will do that authorization but let's say we can explore more let's quickly test the post post and move on this is the post id so this the post returns an array as we have given here it's an array of posts this is not it's a single instance of a post so that we have our person post created so in this in the next section okay let's uh quickly recap so what we have done in this section is that we we imported the authenticate middleware we used the middleware important part is we have to include it before all the routes and in the mutation we added add post where we simply created a post using this data queries we created user post and post which are simple type description arguments and resolve with a mongoose function in the schema so this is our main script right so in the schema we inputted the newly created uh mutation and the queries and we just added that into the root type the root query type and the root mutation type in the hot middle where we find a problem found a problem that we were trying to access um verified user dot id but it was not working so it was me we were the one who added the user if we wrapped up the user into an object so we need access like this we just updated that so in this section we are going to create the mutations and the queries for the comments is going to be very similar to what we did last time going to add add comment so it works very similar to this one the verified user is fed inside by the middleware we have user id we get from the verified user dot id we can write in a very much simpler way but it's fine let's go ahead and test this out and before before that we need to add that add this to the root schema okay let's refresh and see the documentation add comment comment and post id notation add comment there is some spelling mistake here first comment and post id you'll copy from here oh comment is not defined okay mutation the model we did not import the model i thought it will let's try it again we did not create any document yet because we did not import the mongoose um schema in the first place let's try again okay yeah add comment is working let's go ahead and create two queries also maybe let's get lazy and comments id comment post id body title or the title and body it doesn't matter but aesthetics comment is not defined again okay should work now okay here we have our first comment on our first post so in this section we created the mutation mutation and the queries for comments and we added to the schema and things are working in the next section we are going to see the update post and there we are going to see how the authorization we have you know through how to do authorization through our jwt in this section we're going to create update and delete for our posts and comments let's start with the update post and we're going to check if if um our middleware feeds the verified user into the request and can get that from this context the third we can destructure that from the context from the third uh parameter and if it's if it's not there then he did not provide a token he did not basically get authenticated and if you can see we did not actually kick him out or anything here this middleware is not blocking any request it just attaches and it's just passing the passing the next request to the next guy so he is the middleware he trust he authenticates if he is authenticated he attaches a certified user and he just passes passes to another next one this this route and we are accessing that from the mutation so if it's not there we're going to if the verified user is not attached we can safely throw an error saying on authenticated and if not we are going to do this find by id find one and because that's the reason for using find one with update because as the first argument we are going to give two things it's not just id we are not just finding with a id but with authority also which we can get from the verified user dot d next thing is the is the thing we need document we need to change for simplicity we are like changing both the stuff but we can like have a condition here and cook this object depending upon what is being sent or if it's null but it's fine here as a third object we need to pass some options the true is to ask the mongodb to create a new document with the new thing i'm not very sure about it but there is one more thing called run validity test rule that is to validate that run the validations we have in the post schema and we need to make this as async okay if there is no post found post updated if it's not there we're going to throw another error because this condition did not get satisfied we are not just allowing so this this condition is authorization we are doing here we are not just going ahead and updating the we are not just building the client and going going ahead and updating the post id he asked us to update we also have another condition saying that the author id of this post of this particular post we are fetching we are finding should have the authority as the verified user dot id this verified id the object is cooked by the server so this is authorization technique we are using we are going to use the same thing for update and delete also you can pass through errors saying post with a given id found for the author i think and finally let's let's return the post updated let's test it out refresh document should have that a dog has got mad i think update post and we are returning back the post so we can get all this stuff i think that's all and the token is important we have we are actually okay maybe let's pass the invalid token first adjacent e from the beginning unauthenticated where if we pass on authenticated okay so the middleware could not find could not actually verify the token and couldn't could not create a verified thing so it just uh through an error the jbl would verify through any other and we caught here and we did not attach anything so it says unauthenticated let's put it back we will also try it with another jwt we will create another you will create another user we will log in with him he'll also do that okay so it's updated initially it's first force this is our first post and when we refresh body content updated first was updated okay let's create let's quickly create another post and then let's uh go on to delete that post the pose to be deleted body doesn't matter now you have another pose here let's work on delete delete tell it post mutation dog delete post on the okay wait a minute string is equal to abide go start find one and delete and we're going to use the same condition here the first we are going to pass the id or id and author id verified user dot id nothing should work post deleted if there is no post deleted i'm going to throw an error no post with and we can return a string here post deleted let's try that let's copy this id this is the one to be deleted anything but mutations mutation okay i added that to the query actually even now it won't it won't uh it it won't give us the delete post until we refresh but that is that's not a problem we can go ahead and create that i keep refreshing to get the auto complete which is simple which makes things simple delete post and it's going to get the post id which is oh awesome the post id and we're going to return back nothing we just gave that as a string so it will just come back you don't have to do this and as i said it's good to have a custom type instead of just returning a string we instead of just reading returning a string we can have a type for the responses that if that if we do this we can actually like this user type we can create something called a response type or something and we can have fields inside it like that will be much more better but let's just go with this to maintain the simplicity mutation type there is something called state post which returns a string no post with a given id found for the author author id is same for the both let's try to login once again and our password let's also log this one this shouldn't be happening in the delete post we got this fine tone and delay we have author idea authority id these are fine but let's log the verified user here oh okay actually we should also have this check i forgot to have this so if the token has expired or something it's going to throw unauthenticated i know we're getting 30 days it shouldn't have been expired but i'm copying the do the delete post once again it's going to get the post id okay so it still says that specifications access so we have we have the right verified user here and we did not get stuck here but we don't get this unauthenticated error but somehow we are having this problem okay so argument didn't have an id but a full society so this actually is undefined so mongoose mongodb tried to find a document with undefined and the verified user which won't exist so now it should work so i said fail the document is still there so we can retry that it should work post deleted and instead of going ahead let's query the posts posts id title body and we have only one let's quickly create do the same for the comments also i'm going to type this out or or i'm not it looks daunting to me post post post post i'm using ctrl d to select everything with this post spelling delete post post id post okay now we have another problem which is i made everything in small and not capitalized so copy pasting has its problem problems commentary whatever what else comment id update comment here we need caps delete comment fields let's create somewhere some more comments add comment which takes a common unwanted comment or problematic or controversial controversial controversial comment and the post id we have this one fail to fetch comment type is not defined happens all the time yes okay so we have added another comment and let's um let's try to update that first we don't need everything part [Music] update comment is asking for all this stuff okay i think that's all so right now it's showing some error if i refresh it it's going to go away let's do this no comment with the so i attribute all these problems with copy pasting now come out with a given id found for the author but it's a good learning experience comment updated comment updated comment finder not update so arcs author id so you should be now so it's very hard right so the post had of the author id the comment has a user id i did not change that and that caused this problem same should go here so maybe maybe i'm telling the problems with copy pasting okay so actually it returned the it it should have updated it is still there well update what am i saying you said id title body um okay so this is getting frustrated i should have clearly typed this out less controversial comment okay you got it and let's delete that well it has takes only the id and it returns back only the a string it should delete it an argument unknown argument id on the field delete document okay it asks for comment id post deleted and it's not shouldn't be here so yeah so there we have the in this section we created update post update delete and then we also saw some important lessons about copy pasting it it's it screws things a bit and finally it's working i think that's all about the project yeah thanks for watching let's comment this created update and delete for posts and comments post a comment yeah thank you for watching
Info
Channel: Karthick Ragavendran
Views: 3,778
Rating: 4.9699249 out of 5
Keywords:
Id: iQrsckyou_8
Channel Id: undefined
Length: 136min 54sec (8214 seconds)
Published: Mon Sep 14 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.