Build REST API with Node, Express, Sequelize

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what is up guys thank you for joining me for another tutorial today we're actually going to build a node express rest api from scratch we're going to use sqlize we're going to hook up to a postgres database and we're going to use that we're going to build it all as a node application and we're going to do this it's going to be a good boilerplate or a template project that you can actually have and use in in in the future if you have any projects that involve creating a rest api or if you want to experiment on building a rest api this is a good foundation for that we're going to build a create read update and delete route and i'm going to show you how to put all of that together hooking up to the database using the controllers to to perform actions on your data and then returning that that data back to the the end user so um don't forget to subscribe to my channel i'm almost at 500 subscribers that is my next goal so if you can share this video and subscribe to my channel turn on the bell notifications so you can get the the most recent content and be the first one to see it um also if you like this video don't forget to hit that like button everything is appreciated every like every subscription that keeps me motivated to bring you more content and to to talk more about web development and technologies anyways let's get started okay so we all know that the purpose of an api um is to access data from a database and you know do whatever you want with it and transform it or you you know use it in your project in the front end or to analyze it so we in this case we're going to connect to a postgres database so if you notice on the screen here i have a docker compose file open i like to run my my database instances on my machine in docker because it's easy to tear down and clean up and i don't have to install the actual postgres on my computer i could just run a container if i install docker on my computer so that's what this docker compose file is here i'm not going to explain what's going on in this file but right off the top you can see that we're building a postgres container and we're just setting the credentials very basic this is a development database it obviously wouldn't be this basic if it was production you'd have more fancy passwords and usernames and the name of our database is rest we're exposing port 5432 so if i do a docker compose up d and now we have a working postgres database that's running on my computer now if you don't have docker on your computer and don't want to go this route that's fine you can download an instance of postgres on your computer that way that you you can have a local postgres server uh database running on your machine and if you if you don't want to do that either if you already have a postgres database on in the cloud you're more than welcome to connect to that as well you can also connect to a mysql database too i'll show you how to change the drivers to connect to a my sql database if you want but we're going to stick with sql and those are going to be our two options for now you can expand upon that or change it if you'd like to in the future so let's get started basically we're going to open up the project here and so far i don't have anything going on i just have this docker compose file here and i know that for for our structure just like any other project we're gonna have a let's see we're going to have a source directory and that's going to be there and we're going to want to start this project uh initiate this project with mpm just like any other project we're getting ready to start just hit enter to all of these you can put in the name and stuff if you'd like so we have our package.json going and we're going to install our necessary packages okay so we're going to be using we're going to be using emv for our environment variables we're going to use a wonderful package called esm which lets us use the es6 syntax without having to babble it we're going to download express because that's what our server is going to be running on we do helmet for our security headers we're doing logging with morgan i'm going to download pg which is the postgres driver which is going to be used for sqlize and we're going to get sqlize we're going to use version 5.21 let's install that and over here in the source directory i could start setting up some files so when i'm building my my rest api i know that i'm going to use routes or routes so i'm going to build the folder routes i know that i'm going to have controllers two functions to handle the incoming requests and and what response i'm going to send i might have a folder for utilities any functions that i use that i that are that are going to be used repeatedly i can keep them in utilities going back down here looks like our packages are done downloading if we go to our package.json this looks good now the only dev dependency we're going to need is nodemon and that's so that we can run the dev environment and they can watch our server every time we make a change we'll refresh and apply those new changes we're going to have one script for our development environment this is going to be a dev script and we're going to set the development environment the node environment the development we're going to call nodemon and we are going to call source index.js let's save that and now inside of our source directory we're going to have an index.js file and we're going to make a file for the server this is where all of our server code is going to go now nodomon is going to call the index.js file because we're using esm which is an amazing tool i'm going to go ahead and copy and paste this here because i have this already open on another screen and basically it's requiring esm and it's exporting it to and we're going to use server.js so this is going to trans transpile all of our code we don't have to worry about using babel and we can use import we can use all the es6 syntax no problem and it makes things so much easier so if i hit save here that's all good to go so every time i hit npm run dev it's going to set the environment variable to development and it's going to call nodemon and nodomon is going to look over here and it's going to go right here to server.js and call all of our server code so let's confirm our directory structure right now we're also going to need a directory for models and let's make another directory for config okay so let's get the config out of the way first the config is is always one of those things where you just want to just get it over with uh have it get it get it done with and kind of never touch it again you know config.js right away i can tell you that we're going to need an emv file for this because we're not going to want to type in all of our credentials and we're there's possible we can use these variables in other spots too so having an env file is always helpful so i told you that um in the beginning when i open this up i set the password the user in the database here so over here we're going to set some environment variables rest just so the database is rest user postgres password is post local host postgres port is 54.32 and the port for our application is going to run on 4000 so if i save that we have our environment variables for our database set up and ready to go this file would look different on your server so i wouldn't even include this in the um in your git so like we're going to make a dot get ignore and almost all the time you're going to want to ignore the emv file you definitely want to ignore node modules we haven't even initialized this in git yet but this this once we do it we'll ignore this and this right off the bat which is perfect because we don't need to see those on the in our repository it's a security thing so going back to config we're going to require our environment variables in here dot emb config we're gonna export so for our development environment variables we're going to list our databases the first database well actually the only database is going to be rest so and this is our database it's going to be postgres db next thing we're going to put is our username down here we're going to put our password we're going to have the host report and last but not least we need to have a spot for dialect this one we're not using an environment variable we're just telling it use postgres this is where you would put mysql um or the other database of your choice if you're using or anything you would put that here process that we're going to call these environment variables over here this is where they come in handy and we use those so this is our development credentials this should connect to our database now i mean there's nothing there to connect it right now but when it is ready to connect it should call this config and we should connect no problem now you'd have another one set up uh for production as well so if i go to the end here copy this paste it here and i'm going to leave everything the same here because i don't have a production environment yet and when i do put this in production environment this would still work if my emv file has different credentials in it for a production environment it will still pick it up and it will still do the same thing and like i said if you wanted to use my sql instead of instead of postgrads or some other database you'd have to download the driver for it for for postgres it's pg for my sql i think it is actually my sequel um but if you go to sqlize documentation and look up how to connect to a database it will show you the different methods and databases you can connect to so with our config file set we can leave this alone we shouldn't have to touch this for the rest of the application and that's a pretty solid file right there okay so let's just build up a little bit of server.js right now first thing we want to do is import our environment variables in we're going to want to import express and the reason i'm able to use this import syntax remember is because of that esm package right here that points to server.js get rid of that let's import morgan from morgan we're going to be using uh the file system for logging we're going to be using our path and we're going to import our roots so let's set the app equal to express let's use some middleware we're going to use helmet and helmet is really good because it sets up security headers for your application and you don't have to do anything it just does it for you there is obviously options you can find in their documentation on their website right now i'm adding a combined format for for logging we're actually going to stream this to a to a file later on in this video we're going to do a parsing for json we're going to limit that to 50 megabytes on this api you can adjust that to whatever you want or you don't even have to do it really if you don't want to express dot url encoded extended true limit 50 megabytes and we're going to use app dot use we're going to set up our first route route in this api we are only going to have one uh one route and it's going to be able to create read update and delete so we're going to use users for an example so slash user is what our route is going to start off with and then we're going to call on routes.user which is not created yet we're going to have to create that next and of course we're going to want to put a spot for if you if you don't type in the right url you get a 404 message and there you have it we have our basic structure set up here in the server page now we're going to want to turn on our server stop listen we're going to call our port environment variable and once that gets up and running i'm just gonna call that so once we flick on mpmrum.rundev for example it's going to console this as if it starts up and everything's working this is our indicator to let us know that it's on and running now that server.jfjs is set up for the most part we still can't turn this on and have it run with nodemon because we will get errors because we're calling in routes that don't exist yet oh i'm going to make sure we want to save that for good let's exit out of there for now next thing we're going to do is we're going to go to models we're going to create an index.js here and then we're also going to create a inside of models sorry we're going to create a folder we're going to name it rest and inside of here we're going to create user.js this is going to be our actual uh user model and we're going to build this up using sqlize define and we're gonna we're gonna name this table it's gonna be called user and now let's start building out the schema so we're obviously gonna have have an id field and this is going to be an integer it's going to be a primary key and in postgres this is auto uh it's a serial it's called cereal but it's auto increment i'm gonna set that to true and we're going to do a username it's going to be datatypes.string and we're going to want to make that unique so there's only one username allowed of that kind and of course we're gonna do a password so we type data type stop string and you can add validation validation to this as well our parameters like make it a certain length obviously which is what i would do in a production application uh but for now we're just gonna finish our basic schema like this then we're gonna do we are gonna include time stamps and we're going to freeze the table name what did i spell wrong here time stamp stamp steam stamp stampedes stamps we're going to call a sink here to sync our table and this is what i love about sqlize is we don't even actually have to touch uh the database and build our table from the database we could build it right here in code this will build it for us once this is connected and running um and then in this index.js file i'm literally just gonna copy and paste here because this is a standard um you know setup file for sqlize that you can find all over the internet um so you can copy and paste it as well you would have to make sure that all this matches up the only things that need to be fixed in here is obviously make sure your paths are correct like this config file is in fact located over here um and then also you're going to want to make sure that these directories are correct you have one here one here and this is important as well so we're calling uh this directory right here and we're calling the rest folder same over here and for each file in the rest folder is going to be a model and this is our db.rest.import because that's you know the name of our our database our application so db.rest.import let's save that and as far as connecting to the database this should handle it for sqlize but that that's all set let's make a route really quick we're going to do user.js routes and in here we also need an index.js and we're going to import user from user and export default now this is just a spot uh where you know if you had multiple routes uh in a real application you probably have multiple routes you could this is just the the index to pull out of this directory directly that way you can export all your stuff from this file in routes so let's build up our first routes file we're going to import router from express and over here we're going to call a controller file which has not been created yet but we're going to call it user.controller so when it is created that's the file it's going to pull from all right let's save this don't forget actually to export router and there's going to be some some routes going here but let's create this controller file first user.controller.js okay and let's set up you know what let's just do this let's require our models directory which remember this contains all the information to hook up to our database and we're going to declare our model here for users db.rest oh yeah dot user that looks right so let's build our first function and the first one we're just going to call it get user it's going to be asynchronous we're always going to have a request and a response to handle and we're just going to put something simple in here right now okay let me explain what i just did here we're calling in the the user model so that we can use it to find data in our functions here i just created a function called get user and eventually this is going to actually get the user from the database and return it in the response for the api but for now it's just sending you a message saying that this is working i'm exporting it here as well so if i go back over to routes over here bring this controller over here i don't need this file anymore i'm going to declare my first individual route that's going to be router it's going to be a get route and we're going to get user so we're going to use an id and this is going to get us a sing single user get user so i'm calling this function i'm importing it over here the file and i'm calling it right here so whenever i hit this route whenever i hit whenever i hit user slash user it's going to look in routes.user it's going to go over here and this is this route is going to pop up if i have localhost slash user slash and id then it's going to it's going to get my user it's going to return a user it's going to say okay that's this route right here and it's going to call the function over here and ideally this would return the user so with a route in place with a controller in place with the connection apparently hooked up um let's let's try to run this application we shouldn't get any errors here everything looks pretty good for now but you know what you'll never know until you try so running it and successful we have a successful run and if you look here in the in the in the logs it says create table if not exist so we've just created the table for users i already had this database this database created and did a few tests on it but i can show you here that this is what it will create it will create the user table right here so if i actually if i delete this oh why won't it let me connection has been closed great okay so i deleted it so if you're starting from scratch if i save this basically what it's going to do is it's going to call this user.sync and that's what is setting this database up for us so if i refresh this now boom users blank id username password and our timestamps so that is officially set up so if you notice here i have a postman open already and i've already set up four tests for our routes that we're going to eventually create but the first one that we already have created is create i'm sorry get user right here and remember we're calling slash user and then we're adding in an id to grab a specific user's information at this moment there is no user three but i'm putting an id here just so that we can get this thing to to give us something back and if you remember what we programmed was a message saying this is working so if i send this it sends back a message saying this is working now this is big for for our application because now we actually we have our base our foundation set we can connect and officially get back data from the routes that we're creating so this is a huge part in the project because we've actually accomplished a lot with very little so we can we can essentially start building up this controller and get back some real data so the first thing that we're going to want to do is we're going to grab the id from the parameters because it's a parameter in the url and we're going to search for user now in sqlize you have these cool functions like find one which is way better than a select statement and we're gonna search where that id is but if there is no user then we're going to return an error i'm going to just return 400 here you can go ahead and google uh appropriate error codes there's so many of them but you know for for the sake of being quick in this application we are going to just send back a 400 error and we're just going to basically tell them with a message saying that no user was found with this id and besides that we are going to just send them the user if it comes back and that's it this is what our first official uh route looks like to grab a user but we can't grab a user yet if we don't have users in our database so you know what we'll do for the next route we will build one for creating a user and i'm just going to copy this i'm going to paste it here i'm just going to change this to create all right so we're going to be taking in some body information in this because we don't want them putting their password and their username in the url like the get request so we're gonna have to put in the body so we're gonna be pulling from the body and there's two things that we need we need the username and we need the password and if you don't include a username or a password we're going to give you one of these messages just copy paste you need to include a username and password to create a user dummy i mean if you don't include those things and you're trying to create a user it might be safe to say that you're a dummy that's good now we're going to see if this username exists now let's do a user.find1 where username and if username exists we're going to give you another one of these bad boys and we're just going to change the message here a user with the username using string literals already exists bam so that covers that base there and now well let's get rid of this because we don't need this anymore now we're going to create the actual user so i'm going to wrap this in a try catch block and if it errors out we're just going to send an error to the front like this and an airbag i'm going to make this a 500 error and we're going to put the message in here dot message all right so this is where the final part of this route goes we actually create the user here and we're going to return the user from with inside the catch try catch block so let new user equal await user dot create and then we put in our stuff and that should do it that will create our user and then here we'll send new user to the front so we're checking here if you included your username and password if you didn't get error now we're checking if that username exists or not if it does get error and then we're creating the user if it doesn't so let's jump back over to postman now and we have our create a new user thing here so we gotta set up the route for this so if we go back over here to our routes we're gonna do router.get and this one's gonna be create slash create slash create slash create user and we're going to call the create user function boom if you notice down here nodemon is still running the application is still live we're not getting any errors and we can go over to postman now and if we have create a new user here and in postman you're going to go to the body section get rid of this stuff here you raw data and make sure this is usually text make sure it's json and we're going to create an object username let's name this guy admin password is going to be password one two three super secure anyways um send that off for a four page not found so there's something wrong here and i think i know what it is i think we accidentally yep this is not a get route this is in fact a post route okay now this should work boom and we've created a new user with the name admin and the password password123 so if we go back to our database view and if i refresh in here you can see we have a new row admin password123 with our timestamps good to go okay so let's move along actually you know what let's stay here really quick and let's test the the get user uh route so this is user id one right so if i go here put one boom i get my user back so it's working properly um let's make our next close off some of these tabs all right let's make our next route so we're going to i'm just going to copy this see a lot of the stuffs copy paste copy paste and rename this update user okay and then we could leave this here because we might use a lot of this actually we're going to have username and password in the body in case they want to change the username and password is not required because you might not want to change your password when you change your username and vice versa but we're going to declare those variables up here and in the parameters we're going to have the user id so that's how we're going to know what user we're actually updating so we're going to request uh params okay um and then we're going to look for the user to make sure that they exist user.find one where id and then if this user doesn't exist we're just gonna hear here check for user if a user doesn't exist user exists with the id id and then we're going to do our update so i'm going to get rid of this username exists stuff so we're not creating a new user anymore we've pulled our user information here and inside this try catch block we're going to update our information if there is a username user dot username equals the new username if there is password user password equals our new password and we're going to save and we're just going to return a message saying user id has been updated that looks good i think that'll do it so pulling in a username and password if they exist we're getting the id to tell us what user that we're actually updating we're checking for that user if they don't exist we'll give you an error if they do we're updating the information uh that they provide and then we're saving it and this is what actually causes the update to finalize and save so if we go back over to post man go to update user oh we did it again we're gonna have to create our route first so this is called update user for the function we can just paste this here slash update user and remember we're gonna have an id in the params we're gonna do slash id update user up here save that that should be good to go let me go to postman i don't know why this says uh delete and a matter of fact let's let's simplify this route let's name it um just update it doesn't need to be the same as the function it's gonna be update and let's simplify this one too create you want to make them as simple as possible the less typing especially in the url the better so this be uh user slash update and we're updating the user one and so that's good for the url it's a post and in the body we're going to update the username to afk developer so that should do that let's see what happens user one has been updated looks like it was successful let's check here and it was looks good now let's just make sure that the password part is working let's upgrade our password security one two three four five again we're getting a user has been updated message and if i refresh this we have our user updated our password updated good stuff we have one more route to go and we are finished so we're gonna make the delete route and this is a very simple one so let me copy this again if you notice a lot of these are basically you know very very similar so i hope it makes it easier for you to see how i do things because a lot of times you just need to copy and paste some stuff and change the inside of it obviously but so to delete the user we're going to take an id in and we're going to take it in from the body though and if there is no id you send a message saying please provide the id of the user you are trying to delete and then we're going to grab the user like just like this copy from here same exact thing over here paste it here if find the user by the id if the user doesn't exist throw an error that's good and then now we're going to proceed to delete the user let's get rid of this stuff and this is very simple it's literally an awaits user dot destroy command we're going to send back a message saying user has been deleted that should do it save this let's go back over to postman to delete a user so slash delete which is correct because we have to set our route over here no parameters we're going to take the id in the body in this one so we're going to go over to the body and right now i have the id of four in there but we only have one user so it's user number one i'm gonna put this here send it and something is wrong let's cancel this request that body no id user where id id has invalid undefined value here in the body we have requests dot body dot id we're deleting the user up here we have request dot body so let's do some uh debugging together guys and see what's going on here i'm going to comment this code out i'm just going to console.log id and see what happens when i hit this and in order for this to hit um then i can cancel this oh that's what we're doing gosh i am so stupid sometimes forgive me guys that was it's always those little little things that choke you up anyways uh that should be good to go send this user one has been deleted finally go over here refresh they're gone there you have it guys that's a create read update and delete route for you for the users you can make this more advanced by adding password hashing and all that stuff if you look up in sqlize if you look at their documentation they can show you you know different different ways to set that up in the model instance uh where you call functions before you create um but right here is a good place to be for a basic boilerplate template rest api and node in express this will get you started and it is fun to build up on it from here make it your own use whatever routes you want but this is your base so let's add an api key in the middle we're going to have to add a middleware we're going to create a custom middleware so i'm going to make a new file in utils and i'm going to call it is authenticated.js and in this file i'm going to require our environment variables we're going to export const is authenticated if actually if there is no api key in the url query we're going to return we're going to set the status to 401 and we're going to send them a message saying must be authenticated with an api key to hit this endpoint so if they don't put an api key or provide one we can give them this message and we won't let them get their data or else we can pull this api key from the query and if our api key equals process dot emv dot api key return next which basically says keep going finish off this request give them their data back or else we're going to tell them that their key is not valid okay so i'm going to talk about this right here process.a emv.api key so i'm going to set that up here make it a random string now i'm going to set this up here now this is our api key for now if you notice it is static it is in this file so this can be the only api key for this application i wouldn't recommend doing this in production i would recommend having a database for your api keys or api key that way you can find one find the api key so if somebody provides an api key it'll go through and it will look for that api key in the database and you can have multiple api keys if that's the case and then if let's say somebody you want to cut them off from using the api and they're the only one with that api key all you have to do is delete that that entry in the database and now they can't access it anymore but the thing is when you have a static api key it's only looking at one key and this one key is not built in the database so you can't change it on the fly it's actually up uh a string in your file so you have to actually physically go on the on the server and change that api key and it's a pain in the neck especially when you have multiple people using your api you're going to want to make sure you have dynamic api keys but for the sake of this example i'm going to include it right here in the emv file so let's see what happens first let me copy this oh let me apply this go to server.js and this is a middleware so we're going to import is authenticated from our utils slash is authenticated and the middleware goes right here and the middle now if you wanted to use an api key for a certain role or certain routes in the user route then you could just apply it in here as well you can just put it in here and it would actually do it per route and you can you know take it out of here and then if you want like two of these with it and one of them just free without the api key you can do that like this way if you want um but this covers the whole slash user the create read the update all that stuff so if i save this now if i try to create a new user it's going to tell me i must be authenticated with an api key now let's add the api key and see see what happens we're going to add that in the params it's going to be api key and just paste it in there page not found i think it's having a problem reading the emv for this specific situation so i'm just going to copy well i already have this copied but i'm going to go into is authenticated i'm going to try it like this instead i think i've had this problem before page not found oh that's right we changed this we changed this to create made it simple boom there we go the api key is officially working now so we have an api key so we're secure on that end you'll if you want certain people to use your api you can give them the key like i said it's recommended to have dynamic api keys but this is good for now because this shows you how you can do that how you can set up an api key in your api so that you can start locking your stuff down and making sure that it's secure and only certain people that you know are using your api or trust that people are using your api so let's go back and do one more thing we're going to want to let's build some logs because we're going to want to see like what's going on so we're going to actually write those to a file we go to const access log stream i think it's create write stream join and we're going to write it to access.log in the root those are options for flags and this actually goes right here we're going to do stream and we're going to oh put our axis log stream here if you notice it pulled this in but we don't really need that and that should do it if i save here our access log file was created so i can create a user over here let's create a user admin to send it now if you look in access log it will start logging all the requests that are made to the api so this is helpful if you need to to diagnose or debug something but that's it guys this is our you know a basic rest api built with express sqlize node and using postgres this is perfect if you're beginning and to get into creating rest apis or using rest apis and you want to know how they work behind the scenes also it's good if you just need to quick to start an api project and you can use this as a boilerplate i'm going to put it up on github i'll put the link in the description so you can use it you can do whatever you want to it make it custom make it yours and it's always a pleasure and i hope you enjoyed this video if you did make sure you hit that like button don't forget to subscribe to my channel and i'll see you next time
Info
Channel: Christian Martins Web Development
Views: 22,763
Rating: undefined out of 5
Keywords: REST API, Node API, Express API, Sequelize, API Tutorial
Id: 0Yu-4_Vj4sU
Channel Id: undefined
Length: 56min 10sec (3370 seconds)
Published: Thu Dec 03 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.