Coding

Adding Controllers | Creating a REST API with Node.js

  • 00:00:02 welcome back to this series where we
  • 00:00:05 build a restful service with noches we
  • 00:00:07 added a lot of functionality we added
  • 00:00:09 authentication and I'd call our service
  • 00:00:12 finished right now you can always tweak
  • 00:00:15 it can always improve it and definitely
  • 00:00:17 share any tweaks additions or
  • 00:00:19 alternatives you created in the comment
  • 00:00:22 section in this video I wanna have a
  • 00:00:25 look at one improvement it certainly
  • 00:00:27 makes sense so let's dive right into it
  • 00:00:30 and see which improvement that is
  • 00:00:35 as I mentioned you can't do a lot of
  • 00:00:37 things but one thing I want to bring
  • 00:00:39 your attention to it are our route files
  • 00:00:41 we have a look at them you see they're
  • 00:00:44 relatively big now obviously not super
  • 00:00:47 big everything's fine we can leave them
  • 00:00:49 as they are but we could also argue that
  • 00:00:53 in the route files we in the end just
  • 00:00:56 want you distribute our requests we want
  • 00:01:00 to tell them where to go right we want
  • 00:01:02 to tell our get request targeted at just
  • 00:01:05 slash products to go somewhere where it
  • 00:01:08 is code runs that code itself doesn't
  • 00:01:12 necessarily be have to be a part of that
  • 00:01:16 routes file so therefore I will add a
  • 00:01:18 new folder in the API folder and I'll
  • 00:01:21 name it controllers and therefore we
  • 00:01:23 will get closer to an MVC approach
  • 00:01:26 though the via the view is of course
  • 00:01:28 missing because it's a restful service
  • 00:01:30 we don't render a view but at least on
  • 00:01:32 the back end we have our models we
  • 00:01:35 created these with Mongoose and then we
  • 00:01:37 have our controllers where the actual
  • 00:01:40 logic should live and that will allow us
  • 00:01:42 to trade cleaner route files so now I
  • 00:01:45 could create our orders dot J's file
  • 00:01:48 here too and the idea is simple I want
  • 00:01:51 to export a couple of functions here in
  • 00:01:54 the ordered J's files then the end
  • 00:01:57 chests are the same functions as I
  • 00:01:59 passed to my router here so for example
  • 00:02:02 for getting all orders I can grab that
  • 00:02:05 function which I passed to my get method
  • 00:02:09 here like this and cut it out of there
  • 00:02:13 out of my get route and go to the orders
  • 00:02:16 J's file and there I now want to export
  • 00:02:19 it now to export it I'll add exports and
  • 00:02:23 then a name of which under which I want
  • 00:02:26 to export this and here I'll name it
  • 00:02:29 order get orders get all maybe and
  • 00:02:34 assign this function as a value and
  • 00:02:36 that's actually almost all done there's
  • 00:02:39 one thing of course I need to get access
  • 00:02:41 to the order here so I will take the
  • 00:02:44 order import from Mongoose and copy that
  • 00:02:49 and put it into my orders controller
  • 00:02:52 here like this so that I can still use
  • 00:02:55 my order here with that added here I can
  • 00:03:00 go back to my route to the orders jazz
  • 00:03:03 route and import my controller so I can
  • 00:03:06 import the orders controller from and
  • 00:03:11 now let's go up and then to the
  • 00:03:13 controllers folder and the orders file
  • 00:03:15 and now I can simply assign orders
  • 00:03:18 controller that orders get all here as a
  • 00:03:23 function I don't execute it don't pass
  • 00:03:25 parenthesis just a reference to the
  • 00:03:27 function telling DD Express basically
  • 00:03:32 that it should execute this function
  • 00:03:34 this is pointing to whenever we receive
  • 00:03:37 an incoming request here and yeah yeah I
  • 00:03:40 got an error because I worked too much
  • 00:03:42 on the front end it's of course Const
  • 00:03:44 orders ik controller equals require we
  • 00:03:48 should use the nodejs import syntax so
  • 00:03:51 let me save this and let me also make
  • 00:03:55 sure that check off here is of course
  • 00:03:57 incorrect in the orders controller that
  • 00:04:00 should stay in the route foul this still
  • 00:04:02 is my extra check I'm executing here in
  • 00:04:05 the middle where now if that if I save
  • 00:04:07 this it should work and now if I send a
  • 00:04:09 request to orders again I get off failed
  • 00:04:13 so if I do quickly authenticate and I
  • 00:04:17 grab that token here and now use that
  • 00:04:21 new token instead of the old one from
  • 00:04:23 the last recording session I now sent
  • 00:04:26 this this still work so we're still able
  • 00:04:28 to get all the orders now for the
  • 00:04:31 controller keep in mind what I
  • 00:04:33 accidentally messed up but good thing I
  • 00:04:35 guess that the check off middleware
  • 00:04:38 stays in the routes file you could of
  • 00:04:40 course also rule change your controller
  • 00:04:43 to also kind of expose that but I guess
  • 00:04:45 adding the middleware directly here
  • 00:04:47 makes sense so you can easily see okay
  • 00:04:49 any requests reaching that route goes
  • 00:04:52 through that middleware and then
  • 00:04:53 ultimately is handled by this function
  • 00:04:55 here in my orders controller and this is
  • 00:04:59 how we well can set this up and now we
  • 00:05:01 got a very clear
  • 00:05:02 route file at least once we did this for
  • 00:05:04 all the routes so now I will grab the
  • 00:05:07 next one here this is the route for
  • 00:05:10 creating a new order so in the orders
  • 00:05:13 J's file in the controller file I will
  • 00:05:16 now add this and export this as a
  • 00:05:19 function to so I named this one orders
  • 00:05:21 get all here a limit orders create order
  • 00:05:24 maybe assign this function as a value
  • 00:05:28 the one I just grabbed from the routes
  • 00:05:30 file there I also use the product model
  • 00:05:34 and not just your order model so I will
  • 00:05:36 import that you I will import product
  • 00:05:40 wire require models product to get
  • 00:05:43 access to this too and now in your
  • 00:05:46 orders J's file I just want you add this
  • 00:05:49 here orders controller and then its
  • 00:05:51 orders create order and now if we test
  • 00:05:55 isn't postman and I also will add my
  • 00:05:58 authorization header here I'll copy the
  • 00:06:02 one I just used on the get request here
  • 00:06:04 and I'll use this old product ID here
  • 00:06:08 which helpfully works if I now hit Send
  • 00:06:10 here I get product not found so let me
  • 00:06:13 quickly grab all my products yeah all
  • 00:06:17 failed thanks very much so let's add the
  • 00:06:22 off header here quickly to change this
  • 00:06:25 to a get request get all the products
  • 00:06:27 let me now grab this product ID end now
  • 00:06:31 try again by creating an order for this
  • 00:06:33 ID I get an error we have a look at the
  • 00:06:37 log mongoose is not to find yeah makes
  • 00:06:40 sense I guess because here I'm creating
  • 00:06:44 a new object ID by accessing Mongoose
  • 00:06:46 types so we should also add this import
  • 00:06:49 which we have a new routes file so let's
  • 00:06:52 also import Mongoose here in our
  • 00:06:54 controller we need it here too now if I
  • 00:06:57 save disincentives again now we stored
  • 00:07:00 it order so now that is working too and
  • 00:07:02 now to continue in our orders J's file
  • 00:07:05 here in the routes folder we got our
  • 00:07:08 route for getting a single order so I'll
  • 00:07:11 cut this code here to go to the orders
  • 00:07:14 controller and add
  • 00:07:16 here so I'll now have exports orders get
  • 00:07:21 order and assign this as a value and we
  • 00:07:26 got all the imports we need for that so
  • 00:07:28 all I now need to do is go to the routes
  • 00:07:30 file and assign orders controller and
  • 00:07:36 now orders get order if I now save this
  • 00:07:40 and we try this out – in postman now I
  • 00:07:42 want to get a single order why not the
  • 00:07:45 order we just created so let's copy the
  • 00:07:48 ID from that order and attach it here
  • 00:07:51 orders IDs and I get requests to it now
  • 00:07:55 we get that single order so that's
  • 00:07:56 working – and finally for deleting of
  • 00:08:00 course I want to do the same grab all
  • 00:08:02 that code cabott and go to the orders
  • 00:08:06 control controller exports orders delete
  • 00:08:10 order and assign that value here again I
  • 00:08:14 got everything I need I got the order
  • 00:08:16 import already so now in the orders file
  • 00:08:19 in the routes folder I'll simply access
  • 00:08:22 orders controller and then there
  • 00:08:25 it's the delete order and with that if
  • 00:08:28 we save that and we tried try this too
  • 00:08:30 so we delete this order now we got that
  • 00:08:33 deleted response and now we get a very
  • 00:08:36 clean route file obviously we now got
  • 00:08:39 our crowded orders controller but that
  • 00:08:42 is where the logic should live and it
  • 00:08:45 makes it easier for us to understand the
  • 00:08:47 flow of our application of the incoming
  • 00:08:49 requests if we got a leaner route file
  • 00:08:52 at least it is an alternative or an
  • 00:08:54 option you should think about it also
  • 00:08:56 means that we can now remove all these
  • 00:08:57 imports like the order and product model
  • 00:08:59 of course and Mongoose and I only need
  • 00:09:02 Express router my mail aware which I
  • 00:09:04 still apply here and of course the
  • 00:09:07 controller and now we can do the same
  • 00:09:09 for products and users so I can add the
  • 00:09:12 products dot J's file in the controllers
  • 00:09:14 folder and then the product J's file
  • 00:09:17 here in the route folder I will still
  • 00:09:20 he'll still leave the team altars set up
  • 00:09:25 here and the file filter and everything
  • 00:09:28 here which is related
  • 00:09:29 that malt urmila where we could also
  • 00:09:32 outsource this into its own file if we
  • 00:09:34 wanted but I'll leave it here and I'll
  • 00:09:37 now just grab that code for a getting a
  • 00:09:40 single product and getting all products
  • 00:09:43 excuse me and put it into my products
  • 00:09:46 chairs fall there I'll also have exports
  • 00:09:49 products get all and assign this value
  • 00:09:53 and now here we well have the logic to
  • 00:09:56 get all the products I there for all the
  • 00:10:00 needs that import from the product model
  • 00:10:03 in the products J's file now in the new
  • 00:10:06 controller file so that we have access
  • 00:10:08 to that model and let's now try this out
  • 00:10:11 first of all of course let's go back to
  • 00:10:13 the products file and reroutes folder
  • 00:10:15 and let's import so let's import our new
  • 00:10:19 products controller with the required
  • 00:10:23 syntax by going to the controllers
  • 00:10:25 folder and then importing that products
  • 00:10:27 file and now we can use that product
  • 00:10:30 controller here on the get route
  • 00:10:32 so here the products controller with the
  • 00:10:33 products get all method we're pointing
  • 00:10:35 to you and now if we save this and we go
  • 00:10:37 back to postman and send a get request
  • 00:10:39 to slash products we get all the product
  • 00:10:42 so this is working fine now the same of
  • 00:10:45 course for posting a new product I'll
  • 00:10:47 leave to check off and team ultimately
  • 00:10:50 we're in that routing file I'll not put
  • 00:10:53 that into the controller I'll just grab
  • 00:10:56 this function here cut it out of the
  • 00:10:59 route file and create a new function
  • 00:11:01 which I export in my products controller
  • 00:11:04 file I'll name this products create
  • 00:11:08 product here like this in there we now
  • 00:11:13 also again need to import Mongoose to
  • 00:11:15 create that ID so that is an import I'll
  • 00:11:19 get from my products J's file and add to
  • 00:11:22 the products just follow the controllers
  • 00:11:24 folder like this and now we should be
  • 00:11:27 able to create a new product let's try
  • 00:11:30 this out let me quickly send a new post
  • 00:11:34 request here let's add an authorization
  • 00:11:37 header to this post request and in the
  • 00:11:39 body should be form data let's pick a
  • 00:11:42 fitting file and let's
  • 00:11:43 and make sense that we get not found I
  • 00:11:46 should maybe also hook this up here in
  • 00:11:48 the product shares for the routes folder
  • 00:11:50 there for posting I forgot to use my new
  • 00:11:54 controller function so on the products
  • 00:11:56 controller
  • 00:11:57 I want to forward requests to that
  • 00:11:59 function the create product function now
  • 00:12:02 if we save that and go back and try this
  • 00:12:04 same request again it works so now we
  • 00:12:07 successfully added that product now if
  • 00:12:10 we're getting a single product obviously
  • 00:12:12 that's also something I wanna do
  • 00:12:14 so let me cut this code here and go to
  • 00:12:18 the products J's file here and now it's
  • 00:12:22 exports products get product like this
  • 00:12:30 now back in the products file in the
  • 00:12:33 routing folder I'll use my products
  • 00:12:36 controller and use that get product
  • 00:12:39 function we just created and now if I
  • 00:12:42 try to get a single product like the one
  • 00:12:44 we just created so let me get this ID
  • 00:12:46 and set a get request to slash product
  • 00:12:49 slash that ID then it still works so
  • 00:12:52 that's fine now for patching a product
  • 00:12:55 I'll of course do the same copy or cut
  • 00:12:58 the code from the route file add a new
  • 00:13:01 function in the controller so exports
  • 00:13:04 products update product would be a
  • 00:13:07 fitting name in my opinion like this
  • 00:13:10 assign that function we should have all
  • 00:13:13 the imports we need now I'm point to
  • 00:13:16 that function in the routing foul so
  • 00:13:18 products controller update is the
  • 00:13:22 function I want to call and now we have
  • 00:13:25 this too now let's also add our delete
  • 00:13:30 function to our controller by exporting
  • 00:13:35 products delete and assigning this
  • 00:13:39 function here we should all have all the
  • 00:13:43 experts we need here – and now let's of
  • 00:13:45 course also point to that newly created
  • 00:13:48 function in the controller for this
  • 00:13:50 route – and now we got a very clean and
  • 00:13:53 lean products routes file – and then I
  • 00:13:56 said you could
  • 00:13:57 outsource all the Malter related code
  • 00:13:59 here if you wanted to now finally let's
  • 00:14:02 create a new user JS file in the
  • 00:14:05 controllers folder where we manage all
  • 00:14:08 the logic for our user j/s routes so
  • 00:14:11 I'll copy or cut the code here for
  • 00:14:14 trading a new user and export it in the
  • 00:14:17 user J's file here user signup let's
  • 00:14:23 refer to this code I just cut from the
  • 00:14:26 user J's file now we need p-trap we need
  • 00:14:30 Mongoose and I need to use her model I
  • 00:14:33 will actually copy all these imports
  • 00:14:35 because I will eventually need them here
  • 00:14:37 in my controller file so I'll add them
  • 00:14:39 there now we should have everything we
  • 00:14:41 need in the user J's file I now need to
  • 00:14:45 import my controller so Const user
  • 00:14:48 controller is require and now let's go
  • 00:14:52 to the controller controls folder and
  • 00:14:54 import the user file and then here for
  • 00:14:58 signing up I can use my user controller
  • 00:15:00 and use the user signup method point to
  • 00:15:02 it the method I just created and with
  • 00:15:05 that if we test this and we try to
  • 00:15:07 create a new user so for that don't
  • 00:15:10 forget we need to pass an email and a
  • 00:15:12 password field so if we try this out and
  • 00:15:15 I turned this into a post request to
  • 00:15:18 slash user slash signup can remove the
  • 00:15:22 content EDD authorization header set
  • 00:15:25 content to application Jason though to a
  • 00:15:27 raw data here which is Jason and then
  • 00:15:30 simply pass on email which could be test
  • 00:15:33 55 at test comm and a password whoops
  • 00:15:38 like this password she could be test her
  • 00:15:41 and now hit Send
  • 00:15:44 I get not found because that should be
  • 00:15:48 user not users now I get user created so
  • 00:15:52 this works and with that let's also put
  • 00:15:55 the login functionality into the
  • 00:15:57 controller so let's cut this and go back
  • 00:16:01 to the controller and exports user login
  • 00:16:05 and assign this to the function I just
  • 00:16:07 cut and then the user J's file in the
  • 00:16:10 routes folder I'll then point to this
  • 00:16:12 new controller function so to the user
  • 00:16:17 login function and now if we try this
  • 00:16:20 out here and send the post request to
  • 00:16:23 user login with that same data I get off
  • 00:16:27 successful and a token so this is
  • 00:16:29 working to you and now finally let's
  • 00:16:32 wrap that code for deleting a user let's
  • 00:16:35 put that into our controller to user
  • 00:16:38 delete it's pointing to that function we
  • 00:16:41 need to use remodel which we already are
  • 00:16:43 importing here and then the user route I
  • 00:16:46 can then also point to user controller
  • 00:16:50 whoops not delete user delete like this
  • 00:16:54 and now if we try to delete a user and
  • 00:16:57 we therefore quickly grab the idea of
  • 00:16:59 the user we just created and I then send
  • 00:17:02 a delete request user slash with that ID
  • 00:17:06 and I had sent and I turn this into a
  • 00:17:10 valid ID maybe then I get user deleted
  • 00:17:13 so this also works now with that I just
  • 00:17:17 recognized one tiny thing we should also
  • 00:17:21 add the check off middleware in front of
  • 00:17:24 delete to prevent that and authenticated
  • 00:17:26 users to lead our users so that would
  • 00:17:29 make sense so let me quickly add check
  • 00:17:32 off here which I require from my
  • 00:17:36 middleware folder check off like this
  • 00:17:39 and let's simply add it here check off
  • 00:17:41 and now if I try this again and I first
  • 00:17:45 of all try to create a new user
  • 00:17:48 so I post a new user here
  • 00:17:52 whoops user signup of course someone to
  • 00:17:55 create a new one now if I grab that idea
  • 00:17:59 of the new user and I go back to my
  • 00:18:02 delete request and I try to delete that
  • 00:18:06 ID I get all failed and I would first of
  • 00:18:09 all have to log in and delete it and
  • 00:18:11 even then any user could delete an
  • 00:18:13 average user you would have to add some
  • 00:18:15 kind of authorization where you manage a
  • 00:18:17 different table in Mongoose where you
  • 00:18:20 assign roles or permissions to your
  • 00:18:23 users that is something you can simply
  • 00:18:25 add to this application but at least we
  • 00:18:27 got this basic protection against enough
  • 00:18:30 indicated users the cool thing of that
  • 00:18:33 video however will ask that we create
  • 00:18:34 these controllers and we did and now we
  • 00:18:37 have very lean routing files and of
  • 00:18:39 course we can now clean these routing
  • 00:18:41 files up remove user cattle UTEP crip
  • 00:18:44 Mongoose from the user J's file here
  • 00:18:47 only leave the controller and the
  • 00:18:49 middleware and of course Express and
  • 00:18:50 router and for products it's the same we
  • 00:18:53 no longer needs the import to the
  • 00:18:56 product model there so we can remove
  • 00:18:58 that we can remove the Mongoose import
  • 00:19:01 we need Malter still and we need check
  • 00:19:04 off still though and for orders we
  • 00:19:06 already clean this up so now this is all
  • 00:19:09 cleaned up we got leaner route files now
  • 00:19:12 we're using controllers to manage our
  • 00:19:14 logic there and to only manage routing
  • 00:19:17 and the route fault which I guess makes
  • 00:19:18 sense and now it's up to you you can
  • 00:19:21 enhance this application you can try to
  • 00:19:23 add authorization so try to manage
  • 00:19:26 different roles for different users you
  • 00:19:29 can of course add other routes our
  • 00:19:31 functionalities you can exchange
  • 00:19:34 mongoose with my sequel database if you
  • 00:19:36 want lots of stuff there you can dive
  • 00:19:39 into I hope you enjoyed this series and
  • 00:19:42 you'll learn a lot about how you can
  • 00:19:44 build a restful service with note and
  • 00:19:46 Express