Mutations | GraphQL Course For Beginners Ep. 5

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys how's it going i'm back here with another video and today this is the fifth episode of the series where i teach you guys graphql from the beginning and in the previous episodes we built out our at least the beginning of our graphql api you can see that we basically defined a schema that looks pretty nice we have two types of users or two type two types in our application one is called type user and the other is called type movie and we also have our type query which allows us to query users and movies so um this basically taught you guys a lot it taught how to use arguments while defining queries um i also taught how to how to create an enum which was something that i i wanted to show because i don't know i just thought it would be interesting to show in this tutorial and then we also went over how to build resolvers for those functions we're currently using this fake data list over here which just contains a list of users for the user list and there's also a movie list and the resolver is basically just use that list to deal with with what with the data right depending on what they want to return and we also have a resolver for the favorite movies filled inside of user which if you did if you don't remember from the last episode is important because um favorite movies is a field inside of user which doesn't return a like a basic type already existence in graphql it returns a movie which is a type we created so we do need to specify how to get the favorite movies for this user since um in our fake data over here this isn't included inside of the user list so in in the the user that we the data for the user that we get from our single database request it doesn't include a field called um favorite movies so we do need to do that over here at the bottom um when we inside of our resolver so in this video what we're going to go over is basically how to work with mutations which is the other root type that exists inside of graphql similar to query but as you might as i explained in the first episode a mutation it differs from a query because it is basically used to mutate the data to alter the data so if you were using http methods a query would be like a get request and a mutation would be like a like a put a post or a delete request it is used both like for creating data for updating data and for deleting data now we're still using fake data for this tutorial so what i'm going to do is if i want to add a user for example um to our electorate to our data i'm just going to push a new object inside of this user list array and that's how we're going to add stuff into the into our data right and the similar thing will be done with the other types like i'm going to show you guys an example of updating and deleting just to show you guys how you can do that and yeah that's that's basically it before we get into the tutorial if you guys could leave a like and subscribe i would massively appreciate it this tutorial series is actually getting a lot less views than i expected um but it's totally fine because i'm i'm loving this i i love teaching like more complicated topics and i feel like the reason why it's not getting a lot of views is because it's not a beginner video so um it makes sense that not a lot of people would see it and it's one it's probably one of the most worst performing series in the in my channel but it's totally fine because i'm loving it so don't worry i saw some people commenting like don't stop the series i won't stop the series until i feel like it's a good point for to afraid to end and yeah if you enjoyed the series please leave a like because it will help a lot the channel so now let's get into the tutorial [Music] okay everyone so to start writing mutations into our project the first thing we got to do is similar to a query every graphql schema that wants to alter data wants to add data should have a type called mutation so i'm going to come over here and i'm just going to add the type called mutation and similar to query what you do over here is you just write the name of the fields that are going to be able to mutate stuff so for example if i want to have a field which creates uh a user i might just create a mutation a field over here called um create user something like this right and obviously uh similar to like other types in graphql you need to point out that you return something so what is commonly like the standard in graphql is you whenever you create something or you delete or you update something whenever you have a mutation with some sort of type you just return the type so if i'm going to create a user i do all the logic to add the user to my database or in this case just to my fake data file over here and at the end i just returned back the user for for the following reason um graphql deals a lot with um caching so you need to update the the data in the front end so that it is the most it has it isn't the most updated state possible and we'll go like over this more in the next tutorials but for now let's just imagine that whenever we run a mutation we've got to return its new updated values so with the create user um it's something that we want to do it's basically a mutation that will allow us to add a new user to our user list that we created now one thing that we need to take into account is um how do we like know the data that we're sending you can see that each user requires an id a name a username an age a nationality for it doesn't require friends but you can see that those are the ones required and you can add those as well over here um so how do we like allow the user to whenever they make this mutation they send the data required to form a user well it's pretty similar to how you use your past ids and arguments for queries however the difference here is that it is a lot of data so it would be kind of boring to just come over here and just add stuff like oh a name which is a string and age which is an end this would be this would make this huge right and you can do this if you want especially if it isn't a lot of arguments before creating a user you pretty much need to put a name a username an age and a nationality so a common thing you can do is instead of defining stuff like this you can actually just come over here and say that create user accepts a user of type user and then kind of makes sense and you can make this required um but one thing i want to propose is that whenever you you create mutations and you want to put arguments for mutations or anything that is big i would use something in graphql called an input which basically allows you to just like define inputs for arguments whenever you have a field so for example we have this create user over here why don't i just come over here and say input create user input just open and close curly braces like this and then we can specify which fields we want to use to create a user now i understand that this might seem like it's redundant because um literally what we're doing over here is we're just gonna copy and paste this over here and the only thing we're not gonna add for for the input is the the id because obviously like it's not you shouldn't be passing an id you shouldn't need to know the id whenever you create a user um but the thing is there's many practical reasons why you might you need to use an input instead of just directly putting the type as the argument over here and i'm gonna just change this before i explain to you guys but basically and there's a lot of stuff that you can use and do with an input that you can't do with the type for example um imagine imagine that this age variable over here wasn't required it was just like you just accept an integer right um imagine that it just since it's not required i can not pass like i i'm allowed to to not pass an age and this input would be completely correct i would be able to create a user now what happens if i want to say something like um this shouldn't be required the user don't need to send an h but if they don't send the age i want it to default to like 18 years old so if i want to do that i can't do that with the type because that doesn't make sense this is just the structure of the user um whilst over here if i want to do something like that i can just say something like this is equal to 18 and this over here should default to 18 if um if age is not passed this is this is a little trick that works with graphql now in our case we want to make hb required and it also points out that you don't need to pass an id which is important um and that's why you should be creating an input like this so now we're just going to put this over here we already did it as an input and we're going to make it required because you should pass an input to create a user now how do we deal with this how do we go from this field being a mutation to actually creating and adding our like new data into our our table or in our case our fake data array well you can see that if i refresh my my code over here um this is my api it does give me an error which is kind of weird let me go over here to my code it's saying that um oh i got an error which is just saying that um the type of create user input.friends must be an input type but got user this makes total sense and it was a tricky mistake over here you can see that we do have a friend's field right we do have this thing inside of our user called friends but the thing is inside of our input we're saying that if you want to add friends you just have to pass a type user but that doesn't make any sense because we're just creating a user right so what i want to propose is when you create a user you don't pass a movie or friends we're going to do this separately so when you create a user all you need to pass is your name your username your age and your nationality which are the um like the required types and and that we created over here and by the way since i didn't specif since nationality is like not a specific type it's an enum that we created i do want to um be able to allow it to to not be passed to not be required and the reason for that is because when you're working with predefined types that are like this you need you need to account for the fact that maybe someone or for some reason um passes canada but without like capital letters like this and if we make this required completely required it will only will give us an error if it isn't the correct like exactly how we define over here which is something we might want to avoid so what i'm going to do is i'm going to say the nationality is a nationality it's not required but if no one passes a nationality let's default it to brazil and yeah i'm just choosing brazil because i'm from brazil but um yeah this is just an example because i find this really cool and i just wanted to show you guys how this would work in a real application so our user input now is correct let's check you can see no errors are occurring let me refresh over here you should see that um if i just remove this over here i'm actually just going to remove this i'm going to remove the get movie as well from the last episode we still have our query over here um and it's working perfectly if we want to run a mutation um we really can't do anything about it and the reason why we we can't just run a mutation right now is because we created the mutation type over here great user but we didn't actually write any resolvers that actually do something about it that actually gets this input and creates a user so to do that let's come to our resolver.js over here and similar to how we have a query type inside of our resolvers and we also and we have all the resolvers for the fields um for the query and we also have a user type over here for the user we want to have a uh like a a mutation type inside of here so i'm going to put it right below the actually i'll put it below the user like down over here and i'm just going to call this mutation and it's going to be an object which is just going to include like all of the functions related to mutating the data so the first function that we're going to work with is the one that we created has to be the same name so it has to be called create user and we're going to come over here just create the function and it should be fine now one of the things is when you create a user or when you write any mutation you'll probably you'll probably need to like access some sort of argument to the function so similar to how we accessed um like the arguments for the fields that we're requiring the required arguments we're gonna do the same thing we need to get this two things over here from our function and now we can use this args to be um the new user so what i'm gonna do is i'm just going to say const user is equal to args dot input like this input because if you recall we created over here uh like the argument is called input like it has a type input and this includes everything that we create that we want to use so in order to access this i can say args.input and now i get the user info that exists inside of here so now just to see if it's working or not let's just console log this like this and just um console up the user it will give us an error um definitely because we're not returning a user like we said we would um one thing is i'll not make this required i'll just make this um not required for now and let's come over here and let's try to run this mutation to see if everything is working so in order to run a mutation you do something very similar to a query you come over here to where you're going to make the api request you're just going to write mutation then we just open and close curly braces which is a bit different from a query because we were using the name over here we could still give a name for this so i can just come over here and say something like create user um as the name of the mutation and then inside of here i tell which of the fields inside of the mutation type we're trying to access in our case we just have one field which is called create user so i can just say create user over here and you should see that it will because we're using this the polygraph called studio it will automatically generate some of this stuff for us so you can see like it generated our this parentheses over here and all of this information inside i'll just explain really quickly what they mean so when you define a mutation like this and you give it a name like create user um you first grab the variable like the the you create a variable by using this money sign over here and set it equal to b of the type create user input and that means that now we can pass the the input data over here similar to how when you're going to make the request in the frontend you're going to pass the data as a variable to the mutation then inside of here we just say that we call the mutation and we just set the input to be equal to the variable that we created i know this is kind of confusing and believe me it's going to make a lot more sense when we start working in the front end but for now uh this just just go with the flow um we're just going to pass the data inside of this variable and it should be accessible inside of our resolver so for now let's just write something like i want to get an id i want to get the name and i want to get the age and the data i'm going to pass it has to be of a user type or a create user input which just asks us to have a name so let's just pass a name like this name i'll just make it pedro then let's pass uh age so i'll just pass age which would be 20. oh by the way this is j this has to be jason so uh we do need to double quotes this and let me just open this up a bit um the final one it's actually not the final one i think it's uh uh it's username so username even comes before so i'm just gonna say username like this and i'm going to pass page attack and then finally we're going to have nationality which technically we don't need to pass so actually i won't pass just to see if it defaults to brazil now when i click create user you see it gives us no it did work status 200 it did work because we we although we didn't return a user because in our resolver we're currently not returning a user we should see the data that we passed over here being console logged in our server and as you can see this is exactly what happens and it actually defaults the nationality to brazil because we like although we didn't pass any value for it so we know that it's working we know that we can access the user by saying args.input which is amazing so now all we have to do is just add this new user to our um fake data array over here or if in your case you're using any database like mysql or mobdb here's where you add a new field to your like your database table so for us what we're going to do is we're just going to come over here we're going to grab the id of the last user this is something we have to do because um we want to increment the id by one every single time so i'm just going to say const last last id like this is equal to user list and i'm going to grab the last one so i'm just going to say i want to grab the user userlist.length length like this minus one so i'm just grabbing the last element and i want to grab the id from it and this is the last id so what i want to do is i want to construct i want to add to this user type that we just grabbed from the input i want to say user.id i want to add a new id to it and set it equal to last id plus 1 because now if the last id was 5 now the new user we add is going to have an id of six if that makes any sense and then finally i think this is all we need because now all we have to do is we just have to say user list dot push and we're gonna add the new user to the list and at the end we just return this user now let's see if this is working if this is working what should happen is you can see over here if i query all the users like over here i'm just gonna also remove this you should see that um there's no pedro attack over here oh no i'm getting all the movies not users i need to grab all the all the users so i'll just say get all users and let's just query the users field over here and i'm just going to delete all of this because this was the previous query and what i really want to do is inside of here i want to grab the id i'm going to grab the name and i want to get grab the age just for now you can see that all the users none of them just one of them is called pedro so what i'm going to do is i want to add a new user the name is not going to be pedro the name is going to be um elliott and the username is going to be on elliott one two three the age can be 20 as well and i won't pass the nationality again so what we're going to do is we're going to just uncomment the mutation and let's run this mutation again to see what happens you can see first of all we do get the user back because we're now returning the user at the end of the mutation and let's uncomment this and let's run the get all users again to see if the data was actually updated and you can see that it was we now have an elliot and the idea is is 6 and the age is 20 which means um we are actually adding some data to our table now for we're just doing this very simply by just pushing into into array and if you're using a database it should be a little bit more complicated but at the same time just put the logic for like inserting to a database table right over here um instead of having to do like all of this thing over here this is just because i'm using fake data and yeah i i hope you guys got this and this is going to be the flow of creating mutations from now on now since we went over our first mutation i just want to um go a little bit faster for the next ones that we're going to create because um it's going to be pretty much the same so for example we have a create user let's just add a update user right because it might be something that we want to do um let's instead of being update user because um should we do update user actually let's not let's not do update user let's just do um update user name something like this um so we just want to get a new username and update that user that users and username so to do that what we got to do is we've got to create a new input over here and this input is going to be pretty simple we're going to call it update user input or update username you input like this and what it requires is number one uh an id like this because we want to get the id of the user we want to update the the username and then it also requires the new username so let's just write here new username like this and it's going to be a string and what we do is we just put input as a field and we say that it is of type update username input and at the end we should return a user like this now we just create the resolver for it um the resolver is going to be pretty simple again um we're going to just copy and paste this over here what i want to do is i'm just going to grab the um the id for the user i'm going to delete this over here and i just want to grab the id of the of the user when update by saying rx.input.id and then i also want to grab the new username by saying new username is equal to args.input dot new username we could actually have done this a lot easier we could have just done something like this set it equal to args dot inputs and then just grabbing the id and the username by destructuring the object this is a little trick that i would recommend for you guys instead of having to write new lines um do everything in one of them and now we have access to the id and the new username that is going to be passed in the argument so what do we do with it well the first thing we want to do is we want to first of all find the user with this id and just change its username so for to make that i'm actually going to do it pretty simply i'm just going to grab the user list i'm then going to for each like loop through the username or the user list and i'm going to grab each user over here and all i'm going to do is i'm just going to ask if user dot id is equal to the id that we want to update then i want to say that the user.username is equal to the new username like this and this should be fine we're just looping through the user list checking to see if any of the elements in the user list has an id equal to the one that we want to update and if it is then we want to update the username to the new one passed in the arguments and at the end after everything is done i want to do this right here i want to create a variable called user and it can be null right it will initialize it like this and if we eventually find a user and actually that we want to update then we'll just set this user equal to user uh or actually uh i'll just call this user with change actually i'll call it user update it makes more sense and i'll set this equal to the user that was actually found and that has the username updated and then at the end we just return the user updated now there's no guarantee that we're going to pass in the front end an id that actually exists in our table or in our data so this over here can be no which makes sense because we just made our return type to be not required which means that we don't really need to send something back as long as like this allows us to handle errors more easily so let's test to see if this is working let's come over here to our um apollo graphql studio let's get all users you see everyone is working perfectly you can see elliot disappeared because we restarted the server so that's right but one thing i want to do is i want to update the um i want to update sarah's username let's just grab username over here let's see what is sarah's username it is currently cameron um i want to update it so to do that i'm just going to call a mutation over here um i'm going to just copy and paste it like this but instead of create user i'm going to call it update username and instead of being the query user i'll just say update username uh oh damn i just realized this this got pretty confusing so i'll just delete this i'll say mutation update user like this and then i'm just going to say update username as a field and you can see it filled in everything perfectly now we specify which fields we want to get from the user who was updated i'll just grab the id i want to get the username which are the two fields that actually matter so if i come over here and i just remove the create user input and instead i put an input for the update user i need to pass an id the id for sarah is three so i'll just pass three over here then the username for sarah is cameron so we want to update that to um let's make her user name uh i don't know ward like this so this is the data we're passing let's try to run it um it actually didn't work because it said that the field new username required oh i called it new username not username so i need to say new username like this and now that we have the correct name for this variable over here let me just click on update username and it doesn't seem to work which is kind of weird let me just take a look at the code um i don't see anything oh actually damned i already found the error so we called we just copy and pasted the create user mutation function and forgot to change this to update username so this needs to be the same name as the the name we had for our type definitions so now that this is done if i run this you should see that we get back the data and if i actually come over here and i try to get our users again you should see that sarah now has a username word instead of whatever the username was before if i want to update pedro's username to page attack i can just come over here uncomment the mutation again and pass page pages like id s2 and then i'll just come over here change this to i don't know page row one two three and when i click update user we should see that it sends back the correct data and if we query all users again um it should show that both pedro and sarah has updated usernames which means it's working which is awesome and we basically are able now to update stuff inside of our data finally to keep the episodes short um i'm just gonna really quickly show you guys uh delete mutation which is gonna be pretty simple um the first thing i wanna do is just delete all of this because it's kind of annoying me that we have a lot of stuff inside of our um operations like little tab over here then i want to come over here and i just want to add a new field to our mutation let's call it delete user and or i'll just say that it will return a user the user that was deleted but one thing i want to point out is that um when you want to delete a user usually you just have to pass an id right it kind of makes sense you just want to pass an id and delete the user with that id so i'm just going to grab an id i don't even care um to create an input because um in this case it's just one field so it doesn't really matter we don't need to create mult like a hue an input type just for this so now to to finally delete stuff i'll just come over here to our resolvers add a delete resolver by saying delete user and just adding the function we do need to grab the parent again because we need to get the rx because now if i need to get the id from this orgs by saying cost id equal to rx.id then now that we have the id um in order to remove a user with like in a list in an array with that specific id we can just just use the low dash function called remove so we can do something like this just come over here say dodge remove then say that we want to remove it from the user list and then it will loop to the user list and we'll just say that we only want to remove the users which the user.id is equal to the id that of the user we want to remove in our case um and as we did before um like the id will come as a string so we do need to convert it into a number by just saying number id like this and this should remove everything um since we're not keeping track of the user and for simplicity reasons i'll just return no right here we don't really care that much about the user that was deleted and that's kind of most like most cases this happens um but since we just returned everything it seems that we removed it from our array let's test it out how do we get this to work well what we can do is we can just come over here and say mutation and for this one just to show you guys you don't actually need to write the name of the mutation um or query you don't need to give this name this is more best practices and it's easier for organization especially when you're working in the front end but what we can do is we can just say mutation then write delete user and it will actually generate a mutation without a name as you can see over here we do say that we want to get the the field called the lead user and that we need to pass an id so i'm just going to delete the old inputs that we had over here for variables and just leave the delete user id and i want to delete the user um with the id4 rave i want to delete rave over here so i just passed four and for the user that returns back right now we're returning no so i'll just put id over here just for it because or else it will give you an error and let's try running this if i click run you should see null because we are returning though and if i try to run the get all users which by the way if you want to alternate between um stuff that you wrote in your operations tab over here you don't really need to to comment them out um i don't i can't believe i actually just found out it's because it the apollo graphql studio is actually pretty new so i'm still pretty new to it um so i just found out that you just need to click like this and it will keep like alternating between whatever operations you want to make so we just deleted the user let's try to get our users again and you should see that rave is not here because we delete it if i try deleting um kelly over here you should see that um kelly doesn't exist anymore so this is amazing it means our mutations are working it means that our graphical api is pretty much like in a pretty good state right we have some cool queries we have some cool mutations we have some complicated types um we talked we talked a lot about inputs we talked a lot about um different types that you need and how to build your resolvers like this and yeah i'm really excited for how the state of the series is if you have any questions just leave it down below because i'm answering every single question and i really like to help especially regarding graphql so if you liked the video please have a like that below you can know which way next subscribe because i'm posting three to four times a week and i would massively appreciate it and yeah that's basically it really hope you guys enjoyed it and i see you guys next time [Music]
Info
Channel: PedroTech
Views: 1,786
Rating: undefined out of 5
Keywords: computer science, crud, css, databases, javascript, learn reactjs, mysql, nodejs, programming, react tutorial, reactjs, reactjs tutorial, typescript, react js, node js, express js, pedrotech, traversy media, traversymedia, clever programmer, tech with tim, freecodecamp, deved, pedro tech, graphql, graphql course, graphql vs rest, graphql tutorial react, graphql tutorial node, what is graphql, learn graphql, apollo server, apollo client, graphql tutorial, graphql for beginners
Id: Zup4YfDkhCc
Channel Id: undefined
Length: 32min 58sec (1978 seconds)
Published: Thu Sep 02 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.