Coding

MongoDB and Mongoose | Creating a REST API with Node.js

  • 00:00:02 welcome to this video now over the last
  • 00:00:04 videos of this series we already added
  • 00:00:07 quite some functionality to our node
  • 00:00:09 restful services we added our first
  • 00:00:12 routes for products and orders but we
  • 00:00:15 don't really work with the data we get
  • 00:00:18 we don't really manage the data we have
  • 00:00:20 no database we're going to change this
  • 00:00:22 in this video we're going to add MongoDB
  • 00:00:25 as a database and Mongoose as a package
  • 00:00:28 to work with that database to store data
  • 00:00:31 get data and so on so let's dive into
  • 00:00:34 that
  • 00:00:38 so as I said I'll be using MongoDB you
  • 00:00:41 could also use a sequel based database
  • 00:00:43 and you can always search for sequel vs
  • 00:00:46 no sequel to find a lot of discussions
  • 00:00:49 up about when to choose which I'll go
  • 00:00:52 with MongoDB here I might add sequel as
  • 00:00:54 a bonus later in a series but we'll see
  • 00:00:57 and for that I simply google for MongoDB
  • 00:01:00 to end up on MongoDB com now there we
  • 00:01:04 could simply download MongoDB so if you
  • 00:01:08 click on solutions here you can simply
  • 00:01:10 click on try it now MongoDB 3.6 you can
  • 00:01:13 download it and stall it on your
  • 00:01:14 machines set it up connect to it on your
  • 00:01:16 machine you can do all that I'll use
  • 00:01:19 MongoDB Atlas though now what is a
  • 00:01:21 MongoDB Atlas it's simply a MongoDB
  • 00:01:25 database in the cloud managed by the
  • 00:01:29 company behind MongoDB and we can't get
  • 00:01:32 started with that for free why am i
  • 00:01:34 using that because if we think to the
  • 00:01:38 end we obviously want to deploy our API
  • 00:01:41 at some point and building a really
  • 00:01:43 scalable MongoDB on your own so a
  • 00:01:47 cluster of databases replicating data
  • 00:01:50 and all that stuff is something you
  • 00:01:53 probably don't want to do on your own
  • 00:01:55 now MongoDB Atlas does all of that for
  • 00:01:58 you it's a database as a service and you
  • 00:02:00 can work with it just as you work with
  • 00:02:02 it or with you as you work with the
  • 00:02:04 local long going to be you can install
  • 00:02:06 and you can get started for free behind
  • 00:02:09 the scenes is hosted on AWS and as I
  • 00:02:12 said you don't have to pay to get
  • 00:02:13 started so you can simply choose a
  • 00:02:15 region here now I'll pick an American
  • 00:02:18 one North Virginia and then if you
  • 00:02:20 choose m0 as a size so regarding the
  • 00:02:25 power you have available and so on you
  • 00:02:26 see it doesn't cost anything now you can
  • 00:02:29 of course pick a paid one for real
  • 00:02:32 applications but for playing around I'll
  • 00:02:33 use debt now you can see you don't need
  • 00:02:37 a credit card to get started so let's
  • 00:02:39 just get started I'm quickly going to
  • 00:02:41 fill this out here once you did sign up
  • 00:02:44 you can choose their name for your
  • 00:02:46 cluster I'm going to name this node rest
  • 00:02:48 shop because that's what we're building
  • 00:02:50 here you can choose whatever you
  • 00:02:52 you can choose someone going to be
  • 00:02:54 version though here it basically I'll
  • 00:02:57 stick to the default here the cloud
  • 00:02:59 provider so there you could also switch
  • 00:03:01 to a different one but I'll stick to AWS
  • 00:03:03 the region you want to use on the
  • 00:03:05 provider and then important make sure to
  • 00:03:09 select the free tier so the hourly cost
  • 00:03:12 should switch to zero dollars so make
  • 00:03:15 sure that this is selected you don't
  • 00:03:16 accidentally pick a paid one if you
  • 00:03:18 don't want that these are all shared
  • 00:03:20 clusters which might not be the best
  • 00:03:23 choice for running it in production but
  • 00:03:24 for development that's great and then
  • 00:03:27 down there do you want a Charlotte
  • 00:03:29 cluster we don't want to take all of
  • 00:03:31 that you can enable backup but it'll
  • 00:03:33 cost man money thereafter you'll need to
  • 00:03:36 create an admin username and password so
  • 00:03:39 it'll quickly do that obviously you want
  • 00:03:41 to choose a more secure combination and
  • 00:03:43 I did here and then you can click
  • 00:03:45 confirm and deploy now let's quickly
  • 00:03:48 confirm that we're not a robot and this
  • 00:03:51 will set up this MongoDB cluster for us
  • 00:03:53 though here we really will only have one
  • 00:03:55 instance we'll take a little time and
  • 00:03:58 once it's done we'll get the connection
  • 00:04:01 details that allow us to use it in our
  • 00:04:03 node application to connect to it so
  • 00:04:07 even though we're developing the node
  • 00:04:09 restful service on our local machine we
  • 00:04:11 can of course connect to this MongoDB
  • 00:04:13 running in the cloud and again if you
  • 00:04:15 feel totally uncomfortable using that or
  • 00:04:17 you don't want to use it for some reason
  • 00:04:19 you can always install one way to be
  • 00:04:21 locally and then use that local address
  • 00:04:24 that's perfectly fine too now let's do
  • 00:04:26 some useful stuff whilst is working and
  • 00:04:28 let's click on secure it here there you
  • 00:04:31 see the users you created you can all do
  • 00:04:34 whitelist IP so I peace that may access
  • 00:04:36 this instance here and I simply clicked
  • 00:04:40 add Kurt IP address to add my well Kurt
  • 00:04:43 at your IP address or allow access from
  • 00:04:45 anywhere so that of course might not be
  • 00:04:49 what you want you might not want
  • 00:04:51 everyone to be able to access this so
  • 00:04:53 choose whichever setup you want I'll use
  • 00:04:55 that doubt you also be able to access
  • 00:04:57 this again once my IP address changed
  • 00:04:59 and with that setup let's go back to
  • 00:05:03 overview and you
  • 00:05:04 that's not finished yet it is here for
  • 00:05:07 me though you can click on connect here
  • 00:05:11 and connect your application and there
  • 00:05:15 you will find the URL you'll basically
  • 00:05:18 need to use to connect your application
  • 00:05:22 to your instance here you can click copy
  • 00:05:25 here to simply copy that and we'll need
  • 00:05:27 this in our node.js app we'll also need
  • 00:05:30 to replace the password and with that we
  • 00:05:33 could see what they suggest us as
  • 00:05:36 drivers here for a note for example they
  • 00:05:39 suggest your official Mongo client but
  • 00:05:41 I'm going to use Mongoose which is a
  • 00:05:43 different package that makes working
  • 00:05:45 with data with schemas fetching and
  • 00:05:47 storing data super simple so I won't use
  • 00:05:50 their official client I'll use Mongoose
  • 00:05:52 which will build up on this client so
  • 00:05:54 let's leave this page for now and let's
  • 00:05:56 go back to our code there I'll quit the
  • 00:05:59 server and install a new package with
  • 00:06:01 NPM install – – save then Mongoose
  • 00:06:05 that's the package name and – – save
  • 00:06:08 also creates an entry in the package
  • 00:06:10 JSON file now with that finished you can
  • 00:06:14 now obviously start using it and I will
  • 00:06:16 start using it in the app J's fall where
  • 00:06:19 I want to set up a connection now I will
  • 00:06:22 connect to my database here in the
  • 00:06:24 app.js file where we start our
  • 00:06:26 application for that all first of all
  • 00:06:29 import Mongoose here by simply adding
  • 00:06:31 require Mongoose like that and then here
  • 00:06:37 I'll call Mongoose connect and now to
  • 00:06:42 connect I first of all need to pass a
  • 00:06:44 path and here I'll passed path I copied
  • 00:06:47 from our MongoDB Atlas page I dare now
  • 00:06:52 also need to replace the password which
  • 00:06:54 in my case also is node shop and
  • 00:06:57 typically you might want to put this
  • 00:06:59 into some environment variable so that
  • 00:07:01 here you actually access something like
  • 00:07:04 process thought and thought Mongo atlas
  • 00:07:08 password
  • 00:07:10 whenever you chose as an environment
  • 00:07:12 variable name and then you could set
  • 00:07:14 this up on the server you're deploying
  • 00:07:16 this to so that you don't have to
  • 00:07:18 hard coded here into your code now it
  • 00:07:22 used it with node one on the add a new
  • 00:07:23 fall file node montage Jason which I can
  • 00:07:26 use to configure it and there I will
  • 00:07:29 simply add an end key for environment
  • 00:07:32 variables which is an object and there
  • 00:07:34 we can now define all the environment
  • 00:07:36 variables we want to use like for
  • 00:07:37 example here Mongo Atlas PW so I'll add
  • 00:07:42 this here as a name and the value will
  • 00:07:45 be the password we chose on Mongo Atlas
  • 00:07:48 with that we should be able to get this
  • 00:07:50 dynamically and we don't have to
  • 00:07:52 hard-coded in our code now add a second
  • 00:07:55 argument to disconnect function and
  • 00:07:56 object where I will set use Mongo client
  • 00:08:00 to true so that under the hood it will
  • 00:08:04 use the MongoDB client for connecting
  • 00:08:07 which is the recommended way for using
  • 00:08:10 mongoose when using manga version 4.3 do
  • 00:08:14 on our Mongo atlas which is the
  • 00:08:17 recommended way of using this when using
  • 00:08:18 mongoose version 4 or higher which we do
  • 00:08:22 as you can see here now if that let's
  • 00:08:25 try it out and for that let's go to the
  • 00:08:28 routes file and then let's say for
  • 00:08:29 products when we post a new product with
  • 00:08:33 the name and a price let's say we want
  • 00:08:35 to store that in the database now to do
  • 00:08:38 that I will use Mongoose and for that
  • 00:08:41 I'll first of all need a mongoose model
  • 00:08:44 because mongoose and there's no in-depth
  • 00:08:46 mongoose course or video but mongoose
  • 00:08:48 works with models and schemas so you
  • 00:08:50 define how objects you store in the
  • 00:08:53 database should look like and then you
  • 00:08:55 create a model based on that which is
  • 00:08:57 just a javascript object to put it
  • 00:08:59 simple and then this model will have a
  • 00:09:01 couple of functions you can use to save
  • 00:09:04 data update data fetch data by ID by our
  • 00:09:07 criteria order it merge different data
  • 00:09:12 sets and so on so that's what mongoose
  • 00:09:14 offers do for you and it can always
  • 00:09:16 recommend checking out the official
  • 00:09:17 talks to which you'll find a link in the
  • 00:09:19 video description so I'll add a models
  • 00:09:22 folder in the API folder and there are
  • 00:09:24 now add a product or JS file to define
  • 00:09:27 how a product should look like in my
  • 00:09:29 application for Dettol
  • 00:09:32 first of all import Mongoose here to in
  • 00:09:34 store in a constant named Mongoose so in
  • 00:09:37 that and you file and then I'll create
  • 00:09:40 such a schema I'll create a new constant
  • 00:09:43 here and I'll name it product schema the
  • 00:09:48 name is up to you and I will use
  • 00:09:50 Mongoose an unknown goose the schema
  • 00:09:53 method here essentially to which I pass
  • 00:09:56 a JavaScript object which defines how my
  • 00:09:59 product should look like now my product
  • 00:10:03 should have an ID and I'll use
  • 00:10:04 underscore idea which is kind of a
  • 00:10:06 convention which will be of type that is
  • 00:10:10 how you could figure it the value here
  • 00:10:11 is the type of data this will be which
  • 00:10:15 will be of type Mongoose types and then
  • 00:10:17 object ID that's a special type which is
  • 00:10:20 essentially a serial ID not a number but
  • 00:10:25 simply a long string and that's a
  • 00:10:27 specific format Mongoose uses internally
  • 00:10:30 which we assigns the type here then
  • 00:10:32 let's say a product should have a name
  • 00:10:34 and that will just be a string so we can
  • 00:10:36 use the string type like this with a
  • 00:10:38 capital S then we also want to have a
  • 00:10:41 price which should be a number and that
  • 00:10:45 is actually all I want now we'll export
  • 00:10:47 this schema wrapped into a model though
  • 00:10:50 so a schema is like the layout that the
  • 00:10:53 sign of the object you wanna use the
  • 00:10:56 model then is the object itself or gives
  • 00:11:00 you a constructor to build such objects
  • 00:11:03 based on that schema you could say so
  • 00:11:05 I'll set up module exports here and that
  • 00:11:08 is equal to Mongoose model and now that
  • 00:11:15 model function takes two arguments the
  • 00:11:17 first is the name of the model is you
  • 00:11:18 want to use it internally and name this
  • 00:11:20 product the convention here is to use an
  • 00:11:22 upper case starting character and then
  • 00:11:25 the second argument is this schema you
  • 00:11:27 want to use for that model with that we
  • 00:11:29 get our product model setup we can now
  • 00:11:31 use new products J's file in the routing
  • 00:11:33 folder for that I'll import my product
  • 00:11:38 here with capital key here to as a
  • 00:11:40 constant name and I'll import it from my
  • 00:11:44 model
  • 00:11:45 file and they're from the product file
  • 00:11:47 of course that is what we just defined
  • 00:11:49 it now here in post I can use it to
  • 00:11:52 store data for that I'll first of all
  • 00:11:55 trade a new instance of that models a
  • 00:11:57 new product lowercase P maybe where I
  • 00:12:00 use new and then my model as a
  • 00:12:02 constructor now to that constructor I
  • 00:12:06 pass a JavaScript object where I passed
  • 00:12:08 data for that model and there I'll need
  • 00:12:12 to set an ID because we defined that we
  • 00:12:15 want to have a D here and I will import
  • 00:12:19 Mongoose for that with require Mongoose
  • 00:12:24 to be able to create a new object ID
  • 00:12:29 here new Mongoose types and now object
  • 00:12:36 ID as a function constructor function
  • 00:12:39 essentially will give me a new ID will
  • 00:12:41 automatically create one for me and that
  • 00:12:45 will be a unique ID which I can't get
  • 00:12:47 twice then I'll add a name here of
  • 00:12:51 course and that name will be a request
  • 00:12:53 body name and I'll set a price my
  • 00:12:58 request body price that of course means
  • 00:13:01 we can remove the old product we created
  • 00:13:03 here now we got a product object which
  • 00:13:06 is actually created with the help of
  • 00:13:07 Mongoose and that's a special object
  • 00:13:10 where I then call it can call product
  • 00:13:13 safe so save as a method provided by
  • 00:13:18 Mongoose which I can use on Mongoose
  • 00:13:21 models save will then store this in the
  • 00:13:25 database now I can chain a method here
  • 00:13:29 x'q which essentially will turn this
  • 00:13:31 into a promise if I don't call that I
  • 00:13:34 would have to pass a callback here an
  • 00:13:37 arrow function where I either have an
  • 00:13:39 error or the result of that operation
  • 00:13:41 which I of course can do but I didn't
  • 00:13:44 want to use a callback here I want to
  • 00:13:46 use a promise
  • 00:13:47 so I'll chain them here and in there I
  • 00:13:50 will get back the result of that
  • 00:13:53 operation which I'll lock to the console
  • 00:13:55 so result and I also want
  • 00:13:59 catch potential errors sort of all the
  • 00:14:02 chain catch here where I get the error
  • 00:14:05 which I did also want to log to the
  • 00:14:08 console like that so this is how I try
  • 00:14:11 to save that to the database now let's
  • 00:14:13 save that and let's rerun NPM start to
  • 00:14:16 run note 1 again and I get an error here
  • 00:14:19 you see that I got undefined object ID
  • 00:14:23 in my schema file so let's have a look
  • 00:14:27 at what's going wrong there the problem
  • 00:14:30 I have here is I use this a bit
  • 00:14:32 incorrectly this Mongoose type object at
  • 00:14:35 the ISTE constructor function which I
  • 00:14:37 correctly use here in products J s here
  • 00:14:40 to create the ID now to just tell
  • 00:14:43 Mongoose that I want to use this type I
  • 00:14:45 don't use that constructor function of
  • 00:14:48 course instead I have to access Mongoose
  • 00:14:52 schema.org IDs or density correct type
  • 00:14:57 with that if I save this and then I quit
  • 00:15:01 this server and restart it now I should
  • 00:15:05 run without errors and does and now
  • 00:15:08 let's try sending a post request to
  • 00:15:11 slash products which should trigger this
  • 00:15:13 route for that I'm back in postman all
  • 00:15:17 target products here and I will attach a
  • 00:15:21 body to my request
  • 00:15:23 of course not product ID in quantity but
  • 00:15:26 instead a name so here I will use Harry
  • 00:15:29 Potter 5 and you can of course also use
  • 00:15:32 other products and the price which all
  • 00:15:35 set to $12.99 now let me click send here
  • 00:15:38 and I get unexpected end of JSON year
  • 00:15:41 because I mistakenly removed that
  • 00:15:43 closing parenthesis here so let's send
  • 00:15:46 us again and I indeed get back a
  • 00:15:50 response here create a product and this
  • 00:15:53 of course here is the data created by
  • 00:15:56 Mongoose because we're returning the
  • 00:15:58 product which is our Mongoose object so
  • 00:16:01 we're getting back the data which was
  • 00:16:03 safe to the database hopefully now if we
  • 00:16:06 have a look at our log we also see this
  • 00:16:07 log here which is looking good now on
  • 00:16:10 longer DB Atlas it can take some time
  • 00:16:12 until
  • 00:16:12 see it if that really succeeded here in
  • 00:16:15 your dashboard because right now it
  • 00:16:18 hasn't it isn't showing data up to the
  • 00:16:20 point of time when we really wrote this
  • 00:16:22 eventually you should see that you
  • 00:16:24 performed one right action here but we
  • 00:16:27 can simply check by always returning
  • 00:16:29 that data if we access a certain Product
  • 00:16:32 ID so for the get route of products here
  • 00:16:35 I can of course also get this product
  • 00:16:38 with this ID for that I will remove my
  • 00:16:43 dummy code here and instead I want to
  • 00:16:46 use this product model and that's the
  • 00:16:51 object I'm importing here at the top
  • 00:16:53 because I don't need to create a new one
  • 00:16:55 here instead I'll use a static method on
  • 00:16:57 that object which is called find by ID
  • 00:17:00 and it does what the name suggests now I
  • 00:17:03 pass the ID to that and call X SEC and
  • 00:17:06 then I can call them and catch
  • 00:17:09 now let me restructure this over
  • 00:17:10 multiple lines now and then I clearly
  • 00:17:13 want to get my document and here I'll
  • 00:17:16 simply log it to the console for now and
  • 00:17:19 then catch I obviously want to get any
  • 00:17:22 errors I might face so here I'll
  • 00:17:25 console.log an error now right now I'm
  • 00:17:29 not sending a response anymore though
  • 00:17:31 and I want to send a response once we
  • 00:17:33 got the data so I don't want to call res
  • 00:17:36 status and so on after the catch block
  • 00:17:39 because since promises run
  • 00:17:42 asynchronously this would simply mean
  • 00:17:44 that I run the code immediately before
  • 00:17:47 that response is there because code
  • 00:17:50 which I write into this line here will
  • 00:17:53 not wait for all that code to finish so
  • 00:17:56 instead I want to send a response from
  • 00:17:58 inside the den block when I know that it
  • 00:18:00 was successful or also from inside the
  • 00:18:03 catch block but there I want to send an
  • 00:18:05 error so here in the den block I'll use
  • 00:18:08 rest status 200 and I will send back
  • 00:18:12 JSON data of course and let's simply
  • 00:18:15 sent back to talk as we get it so I'll
  • 00:18:18 just set doc here as an argument now in
  • 00:18:22 the catch block I as a just set wanna
  • 00:18:26 actually do more than just logging this
  • 00:18:28 to the console I also want to send a
  • 00:18:31 response there the status code will be
  • 00:18:33 500 though because something failed
  • 00:18:35 whilst fetching the data and I'll set a
  • 00:18:38 JSON response where I will add an error
  • 00:18:43 property which is equal to the error I'm
  • 00:18:45 catching here with that if we save that
  • 00:18:49 file let's try it out let's copy that ID
  • 00:18:51 we got when we created the object and
  • 00:18:53 let's target product slash dead IT ID
  • 00:18:57 with a get request now then let's click
  • 00:19:00 send and I do get back this response
  • 00:19:04 really quick and this does look very
  • 00:19:07 promising because to me that really
  • 00:19:10 looks like we successfully fetched the
  • 00:19:11 data we changed it here and we can also
  • 00:19:15 see that we really have this data from
  • 00:19:17 the database by adding from database
  • 00:19:19 here so we're not seeing some old
  • 00:19:21 version of our code if I click send
  • 00:19:23 again we still get the data and in the
  • 00:19:26 log we see from database so this really
  • 00:19:28 is our update code fetching the data
  • 00:19:30 from the database and eventually you now
  • 00:19:33 see one connection at least here on your
  • 00:19:35 Atlas dashboard if you refresh and wait
  • 00:19:38 a bit you will also eventually see the
  • 00:19:41 reads and writes
  • 00:19:43 you're having on that so we're storing
  • 00:19:46 the data in the database we're getting
  • 00:19:47 it from the database now one thing we
  • 00:19:50 can improve is in the post request right
  • 00:19:53 now I sent my response immediately I
  • 00:19:56 don't wait for this operation to succeed
  • 00:19:59 or fail so just like for getting the
  • 00:20:02 data I want to put my success response
  • 00:20:05 inside the success callback and I will
  • 00:20:08 return the result we get here and for
  • 00:20:11 the error case here I also still want to
  • 00:20:16 lock the error here for us but I also
  • 00:20:18 want to send a different response here
  • 00:20:20 with a 500 error code where I said Jason
  • 00:20:24 or where a sent data in JSON format
  • 00:20:26 where I also have an error property
  • 00:20:29 which holds the error we actually got so
  • 00:20:31 that if something failed we really see
  • 00:20:34 that here too now let's also try a
  • 00:20:37 invalid ID so I'm
  • 00:20:40 get requests for iid I removed the C
  • 00:20:42 which doesn't exist by now Santa's you
  • 00:20:45 see we get an error and there we see
  • 00:20:47 that this couldn't be cast to you an
  • 00:20:49 object ID because it's actually not just
  • 00:20:52 an ID which doesn't exist it's an
  • 00:20:54 invalid object ID and that's detected by
  • 00:20:57 Mongoose if I add a D which now is a
  • 00:21:00 valid object ID by the one which doesn't
  • 00:21:02 exist I simply get back null because
  • 00:21:05 that doesn't throw an error and it
  • 00:21:07 shouldn't it's not an error it's just
  • 00:21:09 that we don't have data for that ID so
  • 00:21:12 we probably in our get function wanna
  • 00:21:14 check for the duck if the doc is there
  • 00:21:19 so if it's not null then I want to send
  • 00:21:22 a response with the doc me document in
  • 00:21:25 the our case I probably want to send a
  • 00:21:28 response which is 404 where I have a
  • 00:21:33 JSON object where maybe I have a message
  • 00:21:36 no valid entry found for provided ID or
  • 00:21:41 something like that
  • 00:21:42 so that now if I save this we actually
  • 00:21:45 have different kinds of answers we can
  • 00:21:47 return we get a 404 answer you can see
  • 00:21:53 the status code here with our error
  • 00:21:54 message if I enter invalid ID if I enter
  • 00:21:57 a valid one with a see at the end I do
  • 00:21:59 get a 200 response and if I do enter an
  • 00:22:02 invalid object ID then I get by 500
  • 00:22:06 response my 500 error so this is how we
  • 00:22:09 can work with MongoDB and Mongoose now
  • 00:22:13 we're fetching an individual product and
  • 00:22:15 we're fetching or we're storing a
  • 00:22:18 product now of course we also have our
  • 00:22:21 general get method where I want to
  • 00:22:23 return all products we have so let's
  • 00:22:27 also take care about this for this I'll
  • 00:22:29 again use my product object up here and
  • 00:22:32 now we can't just use find and if I
  • 00:22:35 don't pass an argument it will find all
  • 00:22:37 elements now you can also add more query
  • 00:22:43 operators here like for example you can
  • 00:22:46 add where to add more conditions to that
  • 00:22:48 query or you add limit to only fetch
  • 00:22:53 a smaller number and you could manually
  • 00:22:55 implement some form of pagination then
  • 00:22:57 here I'll fetch all for now though I'll
  • 00:23:00 call access to get a true promise and
  • 00:23:02 then chain catch and and then
  • 00:23:05 restructure it over multiple lines and
  • 00:23:08 in the den block I'll have all my
  • 00:23:10 documents so all my products and I want
  • 00:23:14 to return them and there I simply want
  • 00:23:17 to console log all Doc's
  • 00:23:19 and then for now return in a response
  • 00:23:22 with status code 200 where I simply
  • 00:23:25 return the docs as JSON data and I'll
  • 00:23:29 also catch any errors we might get here
  • 00:23:32 where I will console lock the error for
  • 00:23:35 us here and we're out there after simply
  • 00:23:38 return a status code of 500 with an
  • 00:23:42 object where I have my error again
  • 00:23:45 provided to our front end now if I save
  • 00:23:49 this let's try a general get request
  • 00:23:52 targeted at products if I sent this we
  • 00:23:56 get back an array with this one object
  • 00:24:01 in there so with this one product that's
  • 00:24:04 great of course that's coming directly
  • 00:24:05 from the database now before we continue
  • 00:24:07 working on this get requests and before
  • 00:24:11 we check which our response you might
  • 00:24:13 return in the van block if we haven't
  • 00:24:15 any data in the database let's make sure
  • 00:24:19 that we can't encounter the case of not
  • 00:24:21 having any data there by adding the
  • 00:24:24 delete functionality now so there I will
  • 00:24:28 now also use product so this model
  • 00:24:31 object and there I can now access remove
  • 00:24:34 and to remove I pass an object which
  • 00:24:38 describes the object I want to remove
  • 00:24:39 and I don't have to pass all properties
  • 00:24:42 I don't have a have to pass an exact
  • 00:24:44 copy of the object I want to remove but
  • 00:24:46 the filter criteria and I'll use the ID
  • 00:24:49 for that and the idea is something I can
  • 00:24:53 get from my URL so I'll store the new
  • 00:24:56 constant pain tidy and I get it from
  • 00:24:58 request parents Product ID and that of
  • 00:25:02 course is just Product ID because that's
  • 00:25:04 the name I chose here so now I'll assign
  • 00:25:07 value here and this essentially means
  • 00:25:09 remove any objects in the database that
  • 00:25:12 fulfill this criteria so that have an ID
  • 00:25:15 property which has the value of this
  • 00:25:17 idea and we should only have one object
  • 00:25:19 dead works like this or that fulfills
  • 00:25:21 this criteria then I'll execute exit to
  • 00:25:24 get a real promise and I'll chain then
  • 00:25:27 and catch now and that as always and
  • 00:25:30 then I get some result which I can
  • 00:25:33 console lock but I'll here immediately
  • 00:25:35 return it set the status code to 200 and
  • 00:25:37 simply return result maybe let's name it
  • 00:25:41 result should not get into conflicts
  • 00:25:44 with the response variable we're using
  • 00:25:46 here and in the catch block I'll
  • 00:25:49 possibly get an error which I'll log to
  • 00:25:52 the console but where I then also want
  • 00:25:55 to return a response with status code
  • 00:25:57 500 where I pass an object which has an
  • 00:26:01 error property that then in turn
  • 00:26:03 contains that error object we got from
  • 00:26:06 Mongoose now let's save this and now if
  • 00:26:09 we grab that ID from the object we got
  • 00:26:11 and we add a T at the end of our URL we
  • 00:26:14 can get the data for that single object
  • 00:26:16 but if we now switch this to a delete
  • 00:26:18 request and click send I get this answer
  • 00:26:22 which I guess means that it worked it's
  • 00:26:26 some data about the process was executed
  • 00:26:30 let's simply try by fetching all
  • 00:26:32 products again with a get request and we
  • 00:26:35 get an empty array so we successfully
  • 00:26:38 deleted the data object that also means
  • 00:26:41 something else we get an empty array and
  • 00:26:43 not null here that's important for our
  • 00:26:46 get method here for our get route here
  • 00:26:50 when we fetch Doc's we return an empty
  • 00:26:52 array maybe we want to do that but we
  • 00:26:56 could also check if Doc's
  • 00:26:58 length is greater or equal than 0 if it
  • 00:27:03 is then I want to return my response
  • 00:27:06 like this else I want to return 404
  • 00:27:12 response and now this is really
  • 00:27:13 something you can think about because
  • 00:27:15 you could also argue that it's not
  • 00:27:17 really a 404 error if we got no data
  • 00:27:19 here
  • 00:27:20 so we'll remove this in a second but I
  • 00:27:22 want to show that you could use this
  • 00:27:24 piece of information and there you could
  • 00:27:26 set up an object you returned with a
  • 00:27:28 message no entries found now again this
  • 00:27:33 is something you can use
  • 00:27:34 but I'll remove that entire check here
  • 00:27:37 I'll comment it out because I think it's
  • 00:27:41 not really an error if we got no entries
  • 00:27:45 in there it's not really like we didn't
  • 00:27:47 find a resource as it is if we try to
  • 00:27:49 query an ID that doesn't exist here we
  • 00:27:52 just want to fetch all products and it
  • 00:27:54 turns out that we got none but that's
  • 00:27:56 not an error at least in my opinion so
  • 00:27:58 I'll leave the setup we had but you
  • 00:28:00 could use that information that the docs
  • 00:28:04 here will be an empty array and not null
  • 00:28:06 for this check to return some other
  • 00:28:09 response if you want it so with that
  • 00:28:12 there is one method we have populated
  • 00:28:15 and that is incoming patch requests
  • 00:28:17 where we want to change our our object
  • 00:28:21 where we want to change data in the
  • 00:28:23 database now let's also work on that to
  • 00:28:25 finish up that product setup here now
  • 00:28:29 updating is simple with Mongoose we can
  • 00:28:32 again use our product model and then
  • 00:28:34 there is an update method now to that
  • 00:28:37 method we first of all need to pass an
  • 00:28:39 identifier for the object we want update
  • 00:28:41 just as we had to for delete for move so
  • 00:28:46 I'll extract the ID from product IDs
  • 00:28:49 from my URL and I'll pass the same
  • 00:28:51 argument as I passed to remove I want to
  • 00:28:54 update an object that fulfills this
  • 00:28:56 criteria that has an ID that matches
  • 00:28:58 this ID then however I also want to
  • 00:29:04 change something about that object now
  • 00:29:08 the second argument describes how we
  • 00:29:10 want to update this this is also a
  • 00:29:13 JavaScript object and there we can use a
  • 00:29:14 special property name dollar sign set
  • 00:29:17 which is understood my Mongoose so this
  • 00:29:20 is not an arbitrary name you have to use
  • 00:29:22 dollar signs set here to then pass
  • 00:29:24 another object as a value to that where
  • 00:29:27 you then describe key value pairs on how
  • 00:29:29 to update your object so for our product
  • 00:29:33 which
  • 00:29:34 has a name and a prize and an ID but we
  • 00:29:37 don't want to change that that's the
  • 00:29:38 idea behind patching we want to keep the
  • 00:29:41 existing object and just change some
  • 00:29:43 properties but if we change the ID we
  • 00:29:45 essentially have the same as if we would
  • 00:29:47 have created a new object so we want to
  • 00:29:49 change name and/or price so here what
  • 00:29:52 I'll do is I will set name to request
  • 00:29:57 and now I expect to get this on the body
  • 00:29:59 so request body new name maybe and the
  • 00:30:04 price to request body new price this of
  • 00:30:10 course assumes that we always pass both
  • 00:30:12 to our endpoint and the idea behind
  • 00:30:15 patches that we don't have to do that
  • 00:30:17 maybe we want to just update the price
  • 00:30:20 or just update the name so we should
  • 00:30:23 check if we really do want to update
  • 00:30:25 both so for that let's add some other
  • 00:30:29 check first I'll create a new constant
  • 00:30:35 which we'll name update ops for update
  • 00:30:38 operations which is an empty JavaScript
  • 00:30:40 object and then I'll trade a loop here
  • 00:30:44 where I'll loop through all the
  • 00:30:46 operations of my request body so I
  • 00:30:50 expect my request body to essentially be
  • 00:30:52 an array here now with that I can use
  • 00:30:56 update ops and add a new property with
  • 00:30:58 that syntax here where I can use Ops
  • 00:31:01 prop name because I expect to pass this
  • 00:31:05 and you will see the other side of how
  • 00:31:08 we pass the data so that here will be
  • 00:31:11 something like name or price and I'll
  • 00:31:13 set it equal to ops value this will give
  • 00:31:18 us an object that in the end will have
  • 00:31:20 this form but only with the operations I
  • 00:31:22 want to perform so here I can now set
  • 00:31:25 update ops and this will be an object
  • 00:31:28 which might have no key value pairs if
  • 00:31:31 we somehow sent a patch request without
  • 00:31:33 a payload then it shouldn't change
  • 00:31:34 anything we might just change the name
  • 00:31:37 or just change the price and with this
  • 00:31:40 dynamic approach we're making sure that
  • 00:31:42 we can really send different types of
  • 00:31:45 patch requests
  • 00:31:47 with that I can as always chain xx to
  • 00:31:50 get a promise and hence chain catch and
  • 00:31:53 then thereafter and and then I'll get
  • 00:31:56 the result which I here wants to log
  • 00:31:59 again and where I don't want to return
  • 00:32:01 and let's again use result here and then
  • 00:32:04 I'll again use response status with a
  • 00:32:08 code of two hundred and Jason data which
  • 00:32:13 is sent back where I will simply pass
  • 00:32:16 the result back to the user and in catch
  • 00:32:20 I'll get a console log where I lock the
  • 00:32:25 error and then I return the status
  • 00:32:27 killed five hundred with why Jason
  • 00:32:29 payload where I have my error property
  • 00:32:32 where I returned the error to the user
  • 00:32:35 with that if we save that file let's try
  • 00:32:39 it out and let's see what happens if we
  • 00:32:41 try to patch an object for that I'll
  • 00:32:44 first of all trade a new one
  • 00:32:46 so I'll post two products and set my
  • 00:32:48 object here quickly run a get request
  • 00:32:51 fine so that's stored let's fetch the ID
  • 00:32:54 and then I'll create a patch request
  • 00:32:57 here now for patch I'll add the ID to
  • 00:33:00 the URL but then I'll also provide a
  • 00:33:02 body where I will set the name to Harry
  • 00:33:05 Potter six now if I send sent is I get
  • 00:33:09 request body is not iterable because my
  • 00:33:13 request body here clearly is still an
  • 00:33:15 object and remember I wanted to use a
  • 00:33:17 different approach I wanted to get an
  • 00:33:20 array where in the array we have objects
  • 00:33:22 that have things like prop name and
  • 00:33:24 value so let's do that I'll actually
  • 00:33:27 pass an array here as a payload which I
  • 00:33:30 can do that's all the valid JSON and
  • 00:33:33 then I could have multiple objects here
  • 00:33:35 and I'll have a prop name property in
  • 00:33:38 here should be between quotation marks
  • 00:33:41 though because we're writing jason here
  • 00:33:43 and the value here will be name because
  • 00:33:47 i want to adjust the name property in my
  • 00:33:49 data and then i'll also have a value
  • 00:33:51 property which holds the new value which
  • 00:33:53 now is harry potter six so now if i send
  • 00:33:57 this we get back status code okay
  • 00:34:01 now let's see if that really works by
  • 00:34:03 going back to a get request and getting
  • 00:34:06 the data and indeed you see the name is
  • 00:34:08 Harry Potter six the price wasn't
  • 00:34:11 touched though and if I go back and
  • 00:34:13 again patch a request and this time I
  • 00:34:17 want to set the price and set it to
  • 00:34:20 let's say 14.10 if I sent this also get
  • 00:34:28 back this script egg response but if I
  • 00:34:31 now get the data for this product we
  • 00:34:34 indeed see the price was adjusted the
  • 00:34:37 name is the same now if I go back one
  • 00:34:40 more time and I patch a new party where
  • 00:34:44 I want to set price new which is a
  • 00:34:46 property we don't define our schema and
  • 00:34:50 I said this back now I get back a
  • 00:34:52 different response and if I get the data
  • 00:34:55 for this object you see this wasn't
  • 00:34:58 added so I can't add new properties like
  • 00:35:01 this I can really just change existing
  • 00:35:03 ones I can't add new ones and this is of
  • 00:35:05 course on purpose I don't want to be
  • 00:35:07 able to add new ones like this we
  • 00:35:10 obviously could rewrite this to allow
  • 00:35:13 the addition of new properties but I
  • 00:35:15 really want you work with a set of
  • 00:35:17 properties that's known in advance
  • 00:35:20 where I can't add new ones and that was
  • 00:35:22 quite some talking and work about
  • 00:35:24 setting everything up setting up moong
  • 00:35:26 or at last connecting Mongoose using
  • 00:35:28 Mongoose creating a schema and model but
  • 00:35:30 now we get a first draft of how the
  • 00:35:33 products routes could work and and look
  • 00:35:35 like if we really use a database
  • 00:35:37 obviously this is not final we might
  • 00:35:40 need more fields than just as a name in
  • 00:35:42 a price but it's nice to get started and
  • 00:35:45 we already achieved something very
  • 00:35:46 important we got a first version of the
  • 00:35:49 restful api where we actually persist
  • 00:35:52 our data in a database and work with
  • 00:35:55 that so let's continue on the road and
  • 00:35:57 let's see which our cool things we can
  • 00:35:59 add to this API