Typescript GraphQL CRUD Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video I want to be showing you how you can create a graph tool API using typescript so we're gonna be interacting with a database and building an example where we go over card operations how to create read update and delete stuff now there's several different ways you can build a graph QL server with typescript I'm going to be showing you my favorite way and the way that I'd build it for my own personal projects so let's go ahead and just jump right into things so here I have a project already kind of set up at least some boilerplate set up and the way I did this is by running the following command MPX create graphical API and then the name of my project now you may not have heard of this because I literally just created it and so this is a CLI that will initialize you with a graph QL server to help you get started a little bit easier so I kind of want to just show you the things that this comes with when you run this command so I thought we started in the package of JSON and just talk about a few packages that I have installed for this the idea is this is it's going to configure a server with a database and typescript so you can just get up and running quicker alright and this is basically what I configure every time that I want to start a new project anyway with this stack so I figured I'd make something simpler for myself alright so first off we're using Apollo you'll notice we're using for the actual server itself Express so Apollo server Express package is a middleware that we're going to stick on Express and it's gonna run the graph killer out we're using graphically well so we need install the graphical package now we are using type arm as our interface or ORM to the database and type Orem uses this this library called reflect metadata we're also using this library called type graph QL so this is an integration that makes it very easy to write graph QL and typescript things that mesh really nice together and we're gonna see why it's nice in a second and this also needs reflect metadata and then lastly I chose to use the sequel light database for this reason being is it's really easy to set up so you don't even need to install database and it has a very compatible API with other sequel databases so after you run this command you just CD into the folder and then you run yarn start and it's going to start up a server for you and we can do database stuff just like that you don't need to install anything else or configure a user because there was there has been some friction with people installing that setting up a database server now normally I would recommend using Postgres that's what I tend to use but this is a great option for dev and you can easily swap everything out they are compatible for mostly everything actually before we leave this one last thing I want to note about this is I'm using no daemon to start up the server so this is going to exec flag here it's gonna run this command so it's gonna run TS node which just runs the typescript nodejs project for us and so what no demon does it's gonna watch our project in our files so if I make a change and save it it's gonna restart for us so it's pretty handy so there is a norm config JSON file this just tells type arm what we're actually using this is like the settings for it the main thing is we told we're using a sequel ID database and here's the name of the database so when you actually run the server with NPM start or yarn start it's going to generate a database that's equal light file and that's where a database is gonna sit and so personally how I plan to use this is to just use sequel Lite and then if you have Postgres installed you can swap it out or when I get to a point where I'm ready to swap it out I can and most of the commands should be compatible all right and then here is the index TS so this is a start and so here we have a function that is asynchronous that calls itself so that's what the syntax is so here you can see this is a function it's wrapped in a parenthesis and it's just calling itself this is just a standard way you'll see people start in their index of TS files and so this is a function that just calls self that way we can have a sink and we can await things so here I am creating an Express instance I am creating a database connection create connections coming from type warm I'm initializing an Apollo server instance you'll notice I am creating the graph QL schema with this build schema function which is coming from type graph QL and then I have a single resolver a hello world resolver which we'll look at in a second and then I'm just getting the context where I get the request in the response and I stick it here I mean so this is a graphical context we'll see more about this later as well and then we just applied the middleware so this is just how Apollo server works when you're setting it up this is how we get it to connect with our Express instance and then lastly I'm just starting the server here app dot listen and the only other thing to show you guys is the hello world resolver so this is a very simple type graphical example so this is a graphical schema that's being generated from this so we can see I have a single query this query returns a string the name of the query is hello and this is what the actual resolver function returns which is just a string it says hi and then I have an entity file this has a user this is mapped to type form this is just an example entity so this will actually create a user table so these will map to columns and then this is kind of like a user table all right so this is what it comes with and this is basically the structure to get you started so now we can actually start adding stuff and in this video we're going to do some crud operations but before we do just to verify that our server's up and running this is what it looks like in the log for me so Express server started and I also have logging on so we can see any kind of sequel like commands that are getting run all right so if we start that server and go to localhost 4000 slash graphic you L will see the graph you'll playground right here and here I can run hello and we can see hi shows up here so if you get this that means you're all set up and you're working correctly we can look at the docs if we want to and so this is where we're gonna start from and so yeah that's the boilerplate CLI that's gonna set this stuff up for you and this is kind of the start of projects usually for me anyway alright so let's go ahead and create a new entity here so I'm gonna create a movie entity ts let's start by saying export class movie and I'm going to make this an entity and we use entity decorator here to say that and this comes from type warm I'm gonna have a number field here and I'm going to say generated this is a primary generated column and all that means is it's going to be 0 than one or it's going to price there at 1 then 2 then 3 then 4 then 5 it's going to automatically pick the ID for me and they're gonna be unique and stuff so we have an ID I'm gonna have a title which is a string so we're gonna say here column and by default type arm will infer the type based on the type script type so this is a type script type here we can explicitly set the type here I actually don't know types for sequel light if I was using Postgres I'd make this a text column but I'm not sure what you use for sequel light so I'm just gonna keep it like this and let type arm in first and here I'm going to have not aged I'm gonna have length which I'm gonna have actually minutes I'm gonna call it minutes because I want to know how long a movie is so this will be number and then here I'm gonna make an int I'm guessing they have an int type I wanted to show you guys that you can also pass and type worm options here of anything you want to set so for example I can set the default movie length to an hour like that oops like that we can also make things for example null noble - true if we want to allow this to be known but I'm not I'm just going to do this alright so I've made my first entity so now I should have a movie table in my database and I'm gonna create a new resolver movie resolver ts and we're say class movie resolver and then I'm gonna say just Oliver and first thing that I want to do is create a mutation so I'm going to use the mutation decorator from type graph QL and so mutations are usually what using graph QL when you want to update or make a change on your server in this case we are gonna create a movie is what I'm going to call it alright so this is a function I'm gonna export my class and before I go any further I just want to import this in my index and I'm gonna pass it as a resolver that gets created here alright so in my create movie guy here the first thing I can do is tell type graphic ul what the return value of the mutation is going to be so by default I'm gonna just return a boolean true or false whether it worked and then we may change this and do different stuff later so we're gonna say true by default and then my function right here I can pass arguments in so I can say argh and this is something coming from type graph QL and so here I can give it a name so for example title which is a string and then I can say title here and then I can say string here oops and we don't even put this here so this is the full thing that you can write here where I'm being explicit about everything so this is the variable name that I want to use in this function so I call it title I said the typescript type is a string and then you'll notice I also did this annotation here and so this part is for type graph QL and for the graph kill schema so I'm just going to do console dot log title for now so because I put this here what this does is this is going to be the name of the argument in I graph QL schema and this is going to be the type in the graphical schema and I can see my stuff is automatically my server restarted for me so I don't need to do anything I'm just gonna come over here and I'm gonna look at the docs and it's kind of it's gonna be blocking you can move it over I'm kind of blocking this but you can see right here that the create movie title returns a string so you can see the argument here and the value it returns and because of that I can name this whatever I want here so I could call this instead name and so these can be different if they want to or they can be the same and just refresh I think it automatically did that's pretty cool we can see the name is here so that's kind of the difference between why we do it here and why we do it here now this I'm explicitly saying that type but type graphic you'll can actually infer that this is a string so we can just leave it like that and we don't have to explicitly declare the graphic you'll type if it's the same now it can't always and for everything so if this was possibly null then I would have to say string and then there's a third parameter here where I can say nullable is true so this is how you can say him knowable argument but okay we're gonna just going to do this for now now I can also do a second argument which I'm gonna call minutes and it's gonna be a number now you'll notice if you're familiar with graph QL number is not a graph QL type it can either be an integer or can be a float so we have to explicitly say here which one it is in my case the minutes is going to be of the type integer and int it comes from type graph QL all right so we have minutes and title we can now create our user now our sorry our movie so here my movie I'm also gonna say extends bass entity this will allow us to use the following syntax I can say movie dot insert and I can insert a movie so I'm gonna pass in a title and the number of minutes at the movie the length of it and I'm just gonna insert that into the database and I'm gonna make this asynchronous here and I'm just wait the insert and we're gonna return true all right we're gonna save this let our database in our database our server restart and then I'm gonna come over here and I'm gonna create a cool it's done now I'm gonna create just a mutation and we have crêpe movie say title it's gonna be Bob of the movie and control space in this editor will bring up the autocomplete minutes this is a 30 minute film and that's all I need to do so we'll run this and it created my movie and we can't really see any of the movie because I decided to just return a boolean here but we can create a query this is usually what you do in graph kill when you want to fetch stuff we can say async actually I don't even think you need to make this async we're gonna say movies and just return them all so what I'd like to do in this statement here is return all the movies so I'm going to say movie dot find and just return them all now I need to specify what the return type is of my query here and one way of specifying this is you'll notice we're going to return an array of movies so we need to actually create the graphic you'll type for a movie now I could create a class up here called graph QL movie type or something like that and I could fill out the fields but one of the cool integrations that you can do with type graph QL and type worm is we can actually go to our entity over here because this looks exactly like the class or the movie graph QL type and so I can annotate these with the field decorator from type graphic ul so you notice I'm gonna put it on all three of these and again this is something where it can infer the type sometimes it cannot infer the number type summer to say this is gonna be an int and again importing from type graph QL and it's gonna be an int and this string it can auto infer so you'll notice I ant ated these three columns with both a type graph QL field and a database field so this is basically reading a 2 for 1 here we're both getting a graphic you'll type out of it and also a database type so this is very handy and very nice integration so over here now I can just say brackets here to signify its array just pass in a movie and that's going to be our graph QL type and one last thing we need to make sure to specify is that this is a object type and so that's how we specify in type graphic ul we decorate the class the object type all right so I can come back over here create a new tab you can say movies fetch the ID title and minutes and nice now I can see my Bob movie here so that went ahead and worked and I could insert more movies if I wanted to and I could see them more here one thing I want to note also is instead of doing the arguments like this one practice that I tend to do especially if you have a lot of arguments to create an input type so the way we can do that is we can say class and I'm gonna call it a movie input and we can say input type decorator just specify that it's an input and we can create some fields here so title which is the string and minutes which is a number and again can it infer it so we're gonna specify that it's an int ear and so now instead of individually specifying the arguments we have a single argument which you could call options for example or input and this is going to be of the type movie input and so we can specify the type here movie input and then here I can just pass the options directly into the insert all right so now notice we can just add fields to this movie input and we don't have to do anything different here or add any more arguments so what does this look like now well when we create a movie instead of specifying the types like this we now say options and we specify a title Bob two minutes this is a 60 minute film so you now pass an object like this so there's just a different way that you can specify this arguments now I also want to when we create the movie give them the option to also return a movie here so I'm gonna return a movie here instead of a boolean and so here instead of inserting one syntax that we can use is the create and save and this will actually return the movie for us and then we can just return the movie from our resolver note with type graph QL I believe or sorry type arm I believe this command this - sequel statements one to create it and one two or one to insert one to select and get the movie after it's complete so that's just something to note I think if you do the insert command you can then do returning and do one sequel statement but this is just kind of a side note all right so our server restarted let's see this in action so I'm going to create this movie and now I want to be able to select the fields here ID title minutes and this is going to be a two minute film and this is Bob point one all right so I can see my create movie here now gets returned and I can go back to my movies and fetch all my movies here awesome all right so that's two of the cruds we can create and we can read I want to do two more let's do an update next so mutation and what we're going to return after a update this is really up to you I'm gonna just say boolean true or false whether it worked so I'm gonna say update movie and so here I want to take an ID so I'm gonna say argh ID and so this is going to be a string and then the second argument so the ID is going to be the movie a to update second argh I'm gonna say options or I can call this new movie value I actually hate that name I'm just going to call it input and we're going to use our movie input here and I'm going to say input is movie input and so inside of here I'm going to return true give this a save and we're gonna say a wait movie and again movie is our entity here so our entity from that we can then call these commands I'm gonna say update the criteria I want to search by the idea and then the thing that we're actually going to update the values that were an update we pass to the second parameter which is the input not sure what is complaining about here oh this should be a number not a string and so we need to specify that that's an int all right so we're gonna give that a save and now I can come over to my schema over here say mutation I'm gonna say update movie and let's update this one right here so he is an ID of three input title we're gonna say Bob point two three and minutes is sixty five so we run this and it got true I'm going to select our movies we can see it updated the two values now one thing you'll notice about this update movie right now is it actually requires me to do both fields I can't just update the title for example and that's because we used our movie and put here and we strictly said you have to supply both these fields so this is one kind of pain point but you will have to create a separate movie input if you want this to work differently so for example I might call this the movie update input and this is where the title can be a string or it can be null for example all right so I'm gonna say this is the type string and possibly know and then this is going to be of type integer and it can be possibly in all and now I'm gonna save or use this input type here in our update movie instead of our movie input and you know what I don't think it's gonna like null here and use undefined all right yeah now it's happy with me all right so now back to our update movie here let's give this a try so let's say I want to update this I want to keep the Mint's to 65 but now I just want to call this movie Tom alright so now let's run this everything looks the same here if I run it here we can see we get Tom but the minutes is 65 so now we can just specify one field right because we made each of these optional all right so that's updating now let's go over the last mutation which is fleeting so how we write a mutation and we're gonna return a boolean from this now we don't really need to copy that we're just gonna say delete movie and get if you want to you could return something differently here besides boolean I'm gonna say Arg ID again we have specify this is an int and I'm gonna say movie dot delete and if I hover over this I can look at the type and this is where I can see what we can actually pass in here it looks like we just pass in that criteria and I can just see we just pass in an ID here and then that will actually delete the movie and so here we create resolvers and this is basically the flow your create resolvers like this we specify the return value of our resolver any arguments it takes and then we usually put our database logic here so let's create a third one here mutation delete movie ID three we get true and now we only have two movies here so that did indeed delete the Tom movie so there you go this was a crud example using type graph QL type arm and Apollo so this hopefully gives you a good idea of how you can do is kind of the starting operations and you can expand it from here and yeah let me know if the comments below if you like the style of tutorial and we can do expanded version of this and add some more functionality you
Info
Channel: Ben Awad
Views: 47,265
Rating: 4.9672132 out of 5
Keywords: typescript, graphql, crud, tutorial, Typescript GraphQL
Id: WhzIjYQmWvs
Channel Id: undefined
Length: 26min 58sec (1618 seconds)
Published: Mon Nov 18 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.