Node.js REST API With Restify, Mongoose, JWT
Lección 1 de 2 · Node.js Rest API With Restify, Mongoose, JWT - Part 1 · Programación
Sobre este curso
[Music] this video is sponsored by dev Mountain if you're interested in learning web development iOS or UX design dev
Mountain is a 12-week design and development boot camp intended to get you a full-time position in the industry to learn more visit dev mountain comm or click the link in the description below
hey what's going on guys in this video we're gonna create a restful api with nodejs and instead of using Express we're gonna use something called Resta Phi which is pretty similar it's kind of
a slimmed down version it's just for restful api is its you know it's not for building other types of applications like you can do with express and we're also going to be using MongoDB for our
database we're gonna use mongoose as an ORM that sits on top of our database so we can easily fetch and add things to the database and so on we're also going to be implementing token-based
authentication in the next video so my goal for this video is to get up and running just a crud basic crud api create read update and delete we're gonna use customers as a resource and
then in the next video we're going to implement authentication so that we can actually log in and you know through postman or through any HTTP client that you want to use and then you'll get a
token back and you'll be able to access protected routes with that JWT token okay so it's gonna be pretty in-depth if you compare it to a lot of other REST API tutorials including some of my own a
lot of them don't do that they don't they don't show you how to actually authenticate and stuff like that it's just it's just wide open so yeah we're going to get into it hopefully I can do
it in two videos we'll do the basic crud API now and then in the next video we'll do the authentication if it takes too long then it might be split up into a few videos all right now as far as rest
if I mean it's just it's just one of many options Express is very popular you have used it over and over I use it in all my courses I wanted to use something different so you have Resta phi you've
koa which is a great framework very similar to Express there pretty pretty similar loopback is another one you have what else happy Jas
so you have a lot to choose from and some people will bash some others just because that's not what they use but they're all very similar they're all pretty they're all pretty similar in
performance some are a little easier to work with than others but I really like rest if I I used it in a project a while ago one of my side projects so I just wanted to do something different and if
you want to use Express that's fine I mean the syntax is just a little bit different ever you know all the Mongoose stuff that's all gonna be the same we're gonna use modern syntax so we're gonna
use like a sync await and stuff like that so it's gonna be very modern code alright so let's get started here I just have the rusta fie website open here if
you want to look at the docs so it's pretty simple you just include rest if I create a server and then you can create your endpoints you want to listen on a port so very similar to how Express
works okay of course we're using Mongoose with Mongoose we have to create database models so our cut will have a customer model and then when we implement authentication we're gonna
have a user model and then we're gonna use M lab for our MongoDB deployment rather than install it locally which I would highly recommend I use M lab in development and in production all right
so let's jump into vyas code and get started so we have a clean slate here just an empty folder called rust off' i underscore customer underscore api we can call your folder whatever you want
obviously I'm gonna be using the integrated terminal in vs code so I'm going to run NPM in it – why so I don't have to answer any questions and that's gonna generate a
package dot JSON file okay so package dot jason holds all your dependencies your your npm scripts all your other stuff like the name and version i know a lot of you guys know
this but just for those of you that don't so we want to install a few things here i'm not gonna insult everything we need i'm not going to install anything that
has to do with JWT the token-based authentication or anything like I said I just want to get like just a basic crud API up running so first thing we want to do
let's install our eye rest if I okay we also want something called Resta phi – errors which will allow us to handle errors more elegantly and then we want Mongoose to deal with our MongoDB
database and then I want to use something called Mongoose – time stamp which is going to add a created at in an updated at field to all of our documents or all of our records so let's go ahead
and run that and those those should all get installed as dependencies so we should see those pop up up here okay so good and next thing we want to do is install node Mon as a dev
dependency so I'm going to say npm install – upper case D node Mon and that will just constantly watch our server so we don't have to keep restarting it when we make changes and that should get
added as a dev dependency okay good so next thing I want to do is add a couple scripts so first of all we want to start script so this will basically run in deployment we're probably going to
deploy to Heroku or maybe digitalocean I'm not sure or maybe not at all it depends so here we're gonna say node index dot JSON let's go ahead and create another script that will be node Mon
index J s and we're gonna call this dev okay so we'll go ahead and save that file and close it up and we want to create two more files in the root one is index JSON as config J s and of course
you can create them from here if you want so config is basically just going to be an object with some environment variables that we'll use throughout the
throughout this application so I'm going to module dot exports an object will have our environment now I'm going to use these process dot in viral in the dot and
and actually this will be our node environment okay so this will be used in production or in development we would just want it to be development so that's our environment next we're going to put
our port number so say process dot Ian V dot port or and then whatever number you want to use in development I'm gonna use 3000 yeah 3,000 okay next thing is going to be our just our base
URL so I'm going to say process dot e NV dot base underscore URL or our URL and development is going to be HTTP local host and port 3000 and then the last thing I'm going to do for now is our
MongoDB URI basically our connection string so URI and for that we're gonna do process dot NV dot MongoDB oops MongoDB URI or and then we
need to put our connection string so we need to actually create a database so let's head over to M lab and this is really easy if you don't have an account just go ahead and sign up it's free
there's you get quite a bit of space for for free for just development no credit card needed so once you sign in or log in you'll see this screen here so you just want to create new and we're going
to choose Amazon Web Services for our cloud provider continue I'm going to choose US East continue and then give it a name I'll just say customer API and continue submit and it should create it
pretty quickly okay so once it's a green check we can go ahead and click on it now you do need to create a database user so I'm going to go to users and add database user and I'm just going to use
ABC one two three exclamation and I'm going to use that for my username and my password ok so now that we've done that you can see up here we have a action string right here this is our URI
we want to grab this and we want to put that right in here okay just make sure you change your DV user to whatever your user is and you also want to change the password so get
rid of this and put in your password I use the same thing okay and that's it for now later on we're going to put our JWT secret in here as well but we're not dealing with with that just yet so
that's good for the config let's open up our index and from here we want to bring in a couple things of course Resta fie so we want to say require Resta fie and we want to bring in mongoose as well
okay we want to bring in our config file that we just created so dot slash config all right so let's initialize restaff I'm going to call this server you can call this app or whatever you want
common convention with resteth is to use server and we're gonna just call Resta phi dot create server okay next thing we want to do is middleware and the documentation lists all the middleware
the only thing that I believe we need is the body parser so we're gonna say server dot use just like Express you do you know usually app dot use and the middleware is in the context of plugins
so we actually want to say Resta Phi dot plugins dot and then body parser okay make sure you put those parentheses on the end after that we're going to take our server object and we're gonna call
listen we want to put our port here so in our config file we want the port value and then we want to put an arrow function here once the server is listening that's when we want to connect
to MongoDB through Mongoose so we're gonna say Mongoose dot connect that's going to take in the connection did the MongoDB URI which is also in our config files so config MongoDB URI one
other thing we want to add here is an object with the value of use new URL parser and set that to true otherwise we're going to keep getting this annoying warning so make sure you put
that in alright so I'm gonna save that I have pretty your installed and with vyas code and I have it to format on save so you can see it just kind of changed it up a little bit made it a little more
readable next thing we're going to do is initialize our DB variable set that to Mongoose dot connection okay and then we want to handle any MongoDB errors we can do that by saying DB dot on DB dot on
error then all I want to do is take the error and console.log it alright okay next thing we want to do is handle the the opening of the database so I'll say DB once because this is only gonna
happen once and then open and when the database opens this is where we basically want to create all of our routes ok now we're not going to list all of our routes in this file we're
going to have separate routing files for each resource so we'll have a customer's file for customer routes when we do the authentication later on we'll have a users file so white right now I just
want to require I want to require dot slash routes we're gonna create a folder called routes and then we're gonna have a file called customers and that's going to explore a function now I want to pass
in the server instance ok so I want to pass this in because that's what we're going to use to actually create routes so server get server dot post and so on alright and then lastly I'm just going
to console log and I'll use back ticks and I'll say server started on port and we'll put in config dot port alright so now we want to create our routes folder so routes
and inside routes we're gonna have a file called customers dot J s this is going to have any routes that have to do with our customers so basically all of our crud stuff now you can see we passed
in server here so we actually want this to explore the function so I'm going to go to customers J s and we're going to module dot exports and you could do function and pass in server like that if
you want I'm actually going to use whoops I'm gonna use an arrow function so I'm gonna get rid of this and just a server like that alright now up here I just want to bring in that Resta Phi
errors because that'll allow us to handle error errors more elegantly so I'm going to say Const errors equals require and we want to pass in Resta Phi dash errors okay so in here's where we
want to make our we want to create our routes or handle our routes so let's create an endpoint here we'll say so server dot get okay so we're gonna handle a get request to slash customers
and it's gonna take in a function ok now this function takes in three things so request response and next now with Resta Phi whenever you're done with your route you you have to call next at the
end ok so don't forget to do that now as far as what I want to happen now I just want to do a rez dot send and we'll just send an object here we'll say message with a string of tests just to test it
out make sure it works so I'm gonna save this and let's clear this up down here and do p.m. run dev okay so you can see server started now if you're getting an error
that says something like something about the Lib Lib slash CLI or something like that what you want to do is just go ahead and delete your node modules folder so you can just do RM dash RF
node underscore modules I'll actually just do it and then just do NPM install or NPM I I don't know why that error happens sometimes but it does alright so that'll just install
everything that's in your package dot Jason okay so now I'm going to run the server again NPM run dev alright now what I'm gonna do is test this route out now you can use any tool you want if you
want to use curl or some other HTTP client I'm going to use postman you can just Google postman and download it it used to be a Chrome extension now it's a standalone tool and it's just it's just
awesome so we're gonna make a get request so I'm going to keep this egg at two HTTP and there it is right there localhost 3000 slash customers I'm gonna send and there it is we get back a 200
response which means everything's okay and then we get an object with message test I know this is really small let me actually make this bigger for you guys so you can actually see what's going on
now next thing we want to do is we want to start to deal with our customers so with Mongoose we have to create models okay we have to create a schema for customers in order to deal with them so
I'm gonna create a folder in the root directory called models and inside models we're gonna create a file called up uppercase C customer dot J s okay so this is going to be our model so first
thing we want to do is bring in Mongoose so we want to require Cryer Mongoose and let's also bring in the time stamps module so its Mongoose – time stamp and I'm just gonna call this time stay
okay next thing I'm going to do is create a customer schema so I want to set that to new Mongoose dot schema and pass in here an object and these are going to be the fields that we want so
we want a name and we want to give it a type it's gonna be a string it's going to be required so we want to say required true and I'm gonna set trim to true as well so that it trims off any
white space underneath that we're gonna have an email so I'm gonna just copy this name paste that in and let's change this to email which is also a string also required also trim and then let's
do a balance okay so balance the type is gonna be a number and I'm gonna set the default to zero okay so if a balance isn't included then the default will be zero so to use
time stamps all we have to do is take our customer schema and call dot plug-in okay because it's a mongoose plug-in and just pass in timestamps our time stamp sorry and that will add a created at and
update it out automatically okay so now what we want to do is create customer and we want to set that to a new mongoose model okay so model called customer and we want to pass in our
customer schema to attach it to that model and then we just want to export it so module dot exports equals customer and that's it that's our model okay so now we can close that up and go back to
our routes file and now we want to bring in that customer model so customer equals say require we want to require dot dot slash models slash customer okay now remember this
here this route this server dot get customers we want to just fetch all the customers that are in the database so I'm gonna get rid of this and what we're gonna do is we want to call customer dot
fine now with Mongoose we could we could say customer I'm just gonna show you could say customer dot find and we pass in an empty object because there's no parameters we just want all of them and
then we could do a call back like this where we do like error docs whoops not Cox don't want Cox least I don't and then arid Doc's we could do it like that we could also use promises which we
are but we could use the standard dot then syntax then catch I'm actually going to use a sink await so I'm going to just create a variable here called customers and I'm gonna set this to a
wait customer dot find now in order to use a wait it has to be inside of a function that's asynchronous so this callback function here I'm gonna mark as a sink so that we can use a wait okay
and it's just gonna basically a wait for the customers to come back because this happens asynchronously and then it'll put it in this variable okay once that happens we want to send it so we'll do
res dot send and we just want to send customers okay and then we want to call next now in order to to do error handling since we're not using the standard then catch we need to wrap this
in a try-catch block okay so we're gonna do try all right and then we'll go ahead and just grab whoops grab all this and let's move this up whoops this up here some fancy keyboard shortcuts catch
okay so catch error so if this if something goes wrong here this is where this these errors come in rest if I errors so I just want to quickly show you Resta fie errors okay
so this is the innocent yeah now these are all the different errors that are available obviously these are all just like HTTP errors so we have unauthorized our forbidden not found all this stuff
and we just want to pass it in the next or is its so we want to do it like this return next new and then errors dot whatever type of error we want so for instance bad request error for this
particular error I'm gonna use the invalid content error so in here let's go ahead and say return next and we'll say new errors dot and I'm going to use invalid C invalid content error and just
pass in whatever is here alright and that should do it now we don't have anything in the database but it should still give us just an empty array so let's save this and let's try it out and
postman so same route slash customers let's send and we get an empty array which is exactly what we should get and we still get a 200 response which is means everything's okay so now that we
can fetch customers let's actually add some so we need to create a route for that let me just put a comment here saying this is to get customers all right and then under here let's do
ad customer okay so for this we want to take our server object and we want to call post because we're making a post request and it's still going to be to slash customers it can be the same
endpoint as long as it's a different method all right so I'm gonna use a single weight here again so I want to mark this as a sink and we want request res next alright so when we make a post
request we want to make sure that the date that the content type is of application slash Jason so let's do a check for that first so we'll say check for Jason so I'll say if and we have
access to that request object we want to say if request dot is application slash Jason okay I actually want to check if it's not so we want to put an exclamation so if it's not then let's
use our Resta fie errors we're going to say return next and in here we'll say new errors and we're going to use invalid or as an invalid content error and I'm going to pass in actually let's
do double quotes here and we're gonna say expects single quote application slash Jason alright so if they try to send something that's not that of that content type they're going to get this
error okay so let's move on and we want to remember we're adding a customer so we're going to create a variable called customer and we're going to set it to a new customer hold on okay I just want to
make sure I thought I put user up here but yeah we're bringing in the customer model so we want to say new customer and in here we want to pass in an object and this is where we want to put the
field so name name and the way that we access the data that's sent from the from in our case postman or whatever your front end is you know if you create if you connected react or angular or
something like that we would get that with request dot body dot name what I'm going to do though is use a little bit of D structuring up here to create separate variables so I'm going to say
Const wrap this in curly braces we want the name the email and the balance okay and we're going to take that out of request dot body and then down here we can do like name name email email but
with es6 since these are both the same we don't even need to to do that we can just simply do name comma email and then balance all right so that will create a new customer object here now what we
need to do is save it to the database because this isn't going to save it it just creates it so down here is where I'm going to do my try catch I'm student let's do error
so we'll say try catch and we want to say new customer equals a weight and this is where we call customer dot save okay and if you weren't using a sync away you could do customer dot save dot
then and so on or you could use a callback and then the response we want to send is just a 201 201 means it's everything is okay but something was created okay so it means created and
then of course we need to call next alright now if something goes wrong here I'm gonna call an internal error so I'm going to say return next and let's say new errors dot
internal error and then this error should have a message so I'm going to say error dot message all right so yeah that should work so let's save this and let's see if we can actually add a
customer so I'm gonna go back to postman I'm gonna open a new tab here choose post ok we want to make it too aged same URL 3000 slash customers now since it's a post request and it has to be Jason we
have to go to headers and add a content type okay now the content type should be like we said application slash Jason alright and then in the body I'm going to choose
raw and I'm gonna pass in some Jason ok so you want to use your double quotes here and it'll say name let's say John Doe email John and Gmail and balance actually it's not do a balance because
it should be 0 if we don't do a balance so let's try it out we'll send okay so down here notice we got a 201 created that's a good sign so let's go back to our this tab where we're making a get
request and send and there he is John Doe his email balance is 0 because we set that as the default an ID MongoDB will automatically give you and what's called an object ID and it's an
underscore ID that's the key and then we have updated and created at because we use the Mongoose timestamp plug-in okay so we can now add customers let's add one more this time let's do like I will
say I don't know Kate Smith Kate and let's let's actually do a balance so balance I'll say 400 so let's try sending that we get a 201 let's go back here and send and there we go she
has a balance of 400 all right cool so next route that I want to create is just to get a single customer okay so I'm gonna put that actually between the two right here and say get single
customer all right and I'm actually going to copy I'm gonna copy the the get customer is right here this whole thing because it's pretty similar so it's gonna be server dot get slash customers
now we need to know which customer to get so we want to do slash : ID we're gonna get it by its ID all right and then as far as our query we don't want to do just find we want to do find by ID
which is a mongoose method and then we want to pass the ID now the way that we get this right here just like with express is request dot params and then whatever that is in this case it's ID
okay and then let's actually call this customer because it's a single customer and then we'll return that customer all right now if that customer is not found I'm actually going to change this error
up I'm gonna change it to a resource not found error let's see right here resource not found and I'm actually going to put in a custom message here I'm going to use back ticks and I'm
gonna say there is no customer with the ID of and then I'm gonna put in a template string here and we'll say request dot params dot ID okay so we'll kind of customize the
response a little bit so let's save this and let's try it out so I'm going to grab one of these IDs here and I'm gonna open up a new tab and we'll make a get request to customers /
and then that ID see what we get and we get John Doe alright so if I change this if I do customers / 1 and I send we get an error here and you can see it has a code of resource not found and then it
has the message that we put in and it'll say there's no customer with the ID of 1 so that's exactly what we want to happen alright so we can now get all customers get a single customer add a customer now
let's work on update okay so we want to be able to update customers so let's go down here I'll say update customer and let's see I'm gonna copy the add customer so I'm gonna copy the server
dot posts that we did and paste that in alright so there's a few things we need to change here so we want this to be a put request because when you update something it should be HTTP put request
and then the endpoint is gonna be customers / : ID because we need to know which customer to update we're gonna keep this Jason check here we're gonna get rid of all this though because we're
not creating a new customer or updating one so we'll get rid of that and in the try-catch block let's change this to just customer and what we're gonna do is take the actual model so this should be
uppercase C because what we're doing is using this directly we're using the the model directly and we're gonna call customer dot and then we're gonna use a method a mongoose method called find
what does it find one find one and update like that okay so we want to find one record and we want to update it and then this takes in a condition so we want to find where that where the
underscore ID is equal to the ID that's passed in the URL and remember we can access that with request dot params dot ID okay and then the next parameter is actually
going to be the data we want to update it with which is going to be request body and the way that this works this find one an update even if we just send the name like we just want to update the
name it'll keep the rest of the data intact and just update the name okay and then the the response we want to send is just a two hundred and then for the error if we were to put the wrong ID in
here this error will fire off that's probably the most common thing that will happen so what I'm going to do is copy this return next up here that we did where it says there's no customer with
the ID so I'm going to put that in the catch okay and we'll save that all right so let's give this a shot I'm going to go back to postman and we're going to open up a new tab and make a put request
okay and let's do this right here this is john doe's ID I want to update him and in headers we want to make sure we put a content type of application slash Jason okay then we'll go to body raw and
then let's put in what we want to change which is going to be his name and I want to change it to John Williams all right so we'll go ahead and send we get a 200 response back so let's go back to our
first tab where we look at all the customers and I'm gonna send make that get request and notice that now John Doe is now John Williams so we can now update so the last part of this of the
this crud functionality is the delete so let's handle that last okay so we'll go under update let's say delete customer and all this code will be in the description if you want to check that
check out the repository so let's just type this out we'll do server now instead of delete we need to do del this is how rest of my works instead of delete we do del and
then the end the end point is going to be customer have I been using customer no customers so customers and then we need the ID because we need to know which one to delete okay we're going to
say async or quest Raz next okay and what we want to do here is our try catch and if you don't like this method if you don't like using a Cinco 8 with the try catch you can just as well use the dot
Bend catch or use the callbacks mongooses is pretty flexible in how you want to write the syntax ok so let's create a variable here called customer and let's set this to a wait and we're
gonna call the customer model and we're gonna call a method called find one and remove ok just like theirs find one and update there's fine one and remove and again we have to pass in the condition
which is underscore ID we want to match that to request on params ID which is what comes in the URL there's no request body there's no data we need to send we're just doing a delete so next thing
we're gonna do is the response so we'll send a 204 which means something was removed ok and then of course we need next and then as far as the error I'm going to do the
same thing I did here which is you know if they put in an ID that doesn't exist we just want to return a resource not found error and that's it that's a delete so let's save that let's go to
postman open up a new tab and let's say delete HTTP let's delete John Williams so this is his ID and that should do it let's go ahead and send okay so we get a 204 no content
let's go back to a get request to customers and send and now John Williams is gone okay so we made a successful delete request if I were to try to delete something that's not there we get
our resource not found all right it'll do the same thing with the update so we now have a full functioning crud restful api all right so there's no authentication or anything like that
we're gonna be doing that in the next video okay so the next video will be a little more complicated we're gonna deal with a couple different modules that we need to install one is the Resta fied
JWT extension and then one is our not extension but package and then also Jason web tokens alright so that's it guys hopefully you enjoyed this I will put the link to the repository in the
description if you want to check it out and that's it I'll see you next time