REST API with Node.js and MongoDB

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome in this video we're going to build a rest API using node.js Express and mongodb if you don't know what is a rest API there's a video here on the channel explaining the basics of Rest by building a complete crude example I'll leave the link on the description below but on the example we build on the video we're not using a database to store the data for this current video we'll be using mongodb which is a document database it stores data in Json format called B it's a database based on a no relational document model and it's also called nosql database uh it defers fundamentally from conventional relational databases such as Oracle MySQL postr or Microsoft SQL Server we'll be using a service called mongodb Atlas which is basically a mongod database on the cloud we can also install mongodb on our personal machine or on a server but for learning purposes we'll be using Atlas which is easy to configure and there's is a free plan that we can use as well you can visit mongodb official website for further information which is mongod db.com and to connect mongodb to our node project we'll be using a module called mongus that provides a higher level abstraction layer for mongodb you can visit Mongo's official website which is mongus j.com and you can check the complete documentation by clicking on read the docks now you can see some examples here as well for node I really encourage you guys to check Mongo's website cuz make things a lot easier for us on the back end we're going to see along the video so let me close the website here and let's start by creating our database on the mongodb website first thing we need to do is to create an account if you don't have one yet on mongodb official website you can click on try free button on the top and you can sign up with your Google personal account or enter your personal information and you can sign up with your personal email and password once you're done you can click on create your Atlas account I already have an account so let me sign in with one of my personal accounts here so the email and click on next and enter the password and click on login okay okay so this is the mongodb Atlas dashboard and if you check here on the top there's a drop- down containing all projects we have mongod DB Atlas already created a project for us by default which is Project zero we can rename this project to something else by clicking on view all project and on the project list which we have just one select the project and click on the three dot button on the end then select the edit project option it's going to show a dialogue so we can enter the new name of our project so I'll just put here main project in Upper camo case but you can put any name you like okay perfect so let's click on our main project to create our database and to do so we need to create a mongodb cluster which is a term used for a database replica set or share deployments in Atlas a cluster is a distributed set of servers used for data storage so to create a new cluster we can click here on create or we can go on the left menu here under deployment click on the database option and on build a database button here okay so when you sign in for the first time this is the page that you might see first okay so to create the database we need to select one of the plans here on the top and we'll select the last one which is a free plan next we need to select a provider and we have AWS Google cloud or Azure uh I'll just leave as AWS next we need to select a region where our database will be stored uh make sure to select a region that is close to where you are I'm in s Paulo Brazil right now so by default Mongol Atlas selected the closest region so I'll just leave as it is next we need to give a name to our cluster by default Mongol Atlas add the name as cluster zero so let's change to main cluster upper camo case as well but feel free to put any name you like and the last option we can add some tags to our cluster but this is optional so I'll just leave without it we can go ahead and click on create okay so on the next page we need to enter some security settings here first we need to specify a username and a password to access our database by default the username is the same as your email address but we can change if we want I'll just put manra here and for the password we can click on autogenerate secure password to generate a random password or we can enter one uh I'll just add manra 123 cuz it's easy to remember and we'll be using this information to connect to our database okay so we can click on create user and next we need to specify the IP addresses that can access our database uh by default Atlas already added my IP address here but let's say we deployed our node project on a different server so we need to add the IP address for that server as well we can add the IP address and add a description so we know from who that IP address is if your IP address is not down here so for example let me remove my IP address here then we can click on add my current IP address to add it to the list so now our computer have access to our cluster where will be our databases as well we can click now on finish and close to complete the cluster creation it will show a success dialogue we can click on go to overview and perfect so we're back on the Atlas dashboard but now we have our main cluster here and we can create multiple clusters but on the free plan we can only have one and to connect to our cluster we can click on the connect button here and it will show a dialogue with different ways to connect so for example we can click here on drivers option to connect to our node project it will show the steps that we need but we'll be using this option later on the video for now we'll need a software to check our database and all its data and a good and free option that we have is called Compass so let's click on the compass option here and Compass is a powerful guwi for querying and analyzing our database in a visual environment so if you don't have Compass installed you can click on don't have mongod DB comp as installed and you can select the operation system that you're using here on the drop-down and click on the download Compass button once you have Compass installed you can click here on I have mongodb Compass install button and it will show a connection string to connect Compass to our cluster so let me open compass here and this is the first screen that will appear once you open compass for the first first time and let me copy that connection string by clicking here on the copy icon and back on Compass as you can see here we have a text field to add the URI which is the connection string Under the new connection option so let's paste the connection string here okay perfect now we need to change the password variable that we have over here to the password we created for our manra user which is manfra 123 now we can can click on connect and perfect so we connected mongodb Compass to our mongodb cluster and as you can see here by default mongodb created two databases which are admin and local these are internal databases we should not touch them unless advised by mongodb support or special admin tasks so let's just ignore them and to create our own database we can click here on the plus sign next to the databases option it will show create database dialogue where we can enter the name of our database and our first collection as well so collection is the same as a table on a SQL database here on mongodb the tables are called collections but for now we won't create our database here on Compass we'll create directly from our node project using mongus so let me close this dialogue and the connection Dialogue on mongodb Atlas as well so our mongodb close is created and ready to use so let's get started on coding I'll be using vs code for the tutorial but feel free to use any code editor you like and here on vs code I have a folder open called restore API undor nojore mongodb you can put any name you like the folder is empty we're going to create everything from scratch let's start by creating our node project I'll click here on the top to open the terminal and the common to create a new nodejs project is n cam in it and if we hit enter it's going to ask a few questions like the name of the project the author if there's a g repo we can leave everything as the default answer so we can add a flag which is dasy to answer everything as default and we can change this information later so hit enter and perfect as you can see we have a new package Json file which contains all information from our project and we can change this anytime all the dependencies will'll install will be be on this file as well let's do that now actually uh let's install the modules we'll be using so back on the terminal let me clear this and to install dependencies uh we can type npm install and the first module we'll be installing is Express which is a framework to handle routes requests and responses easier and of course there's a lot more features and the next module is mongus to handle the connection with mongodb and also manipulate data really easy to use we'll see during the video so now just hit enter to install these dependencies and perfect as you can see in the package Json file we have the dependencies express and inside the dependencies object and there's also a field here called main which is equals to index.js so this will be the main file of our project the starting point we can change the name if we want but I'll live as it is so we need to create this file in the root of our project so here on the root right click new file and the name will be index.js great so like I said before this will be our main file so let me close the terminal and the package Json file and let's work only on the index.js file so the first thing we need to do is to import Express here on the top so con Express equals to require Express okay uh I'll import mongus as well right below the Express in import so cost mongus equals to require mongus great next we need to initialize Express by calling the express as a function and we'll start inside a constant so const app equals to express function okay finally Express needs to listen to a specific Port so our server can run so below the express initialization I'll call app Dot listen and the first parameter will be the port number so I'll just put 3,000 here and the second parameter is a call back if everything's running I'll just put a message on the console so I'm going to put here the arrow function and console.log and inside I'll just put a message here saying server started on Port 3000 okay great so let me save this file and let's run everything on the terminal to see if it's working so I'll open the terminal here on the top and let me clear this first and the comment to run this file is node index.js hit enter and perfect as you can see Server started on Port 3000 that means our server is working and let me stop the server by pressing contrl C and and right below the express initialization let's create our first route and it's going to be a get route okay so app.get and the name of this route is just going to be a slash that means it's going to be the Home Route okay and next uh we'll receive here two parameters uh the first one is going to be the request and the second parameter is going to be the response okay so now I'm going to put an arrow function here so the request is everything that the front end sent to us like a Json or a parameter in the URL and we can manipulate inside the function here and the response is what we need to send back to the client with a status code maybe a message or a data and we're going to do all this inside this function so let's do that right now let's send a response to the client so response do send and inside we'll just send a message here saying something like success okay perfect so let's test all all these changes I'm going to save the file and back on the terminal I'm going to run again node index.js hit enter okay server started and to test the routes I'll use a software called Postman Postman is a tool to test HTTP requests there are other softwares out there so feel free to use one that you like to open a new HTTP request we can click on the plus sign on the top bar this will open a new tab here and we can choose the HTTP method here on the drop- down and we also have the URL field here let's type the Home Route that we created so HTTP column SL slash Local Host column and the port number which is 3,000 to test this we can click on send on the top right and perfect so we got the response message success and the status code 200 okay which indicates that we got a success response great so back on vs code we need to configure Express to accept Json requests from the client in our case is Postman So Below Express initialization let's call app do use and inside Express do Json function okay so let's change our route to accept a request body from the client let's change the method here from get to post and inside the route let's log the request body to see if everything is working so console.log and requestbody great so let me save this file and back on the terminal let me stop the server crl C and type again node index.js hit enter okay server started back on Postman now here on the method dropdown let's change this to post and we need to send ad Json body to the server to send data we can click on the body Tab and there's different ways to send data to the server we'll choose the raw option here and on the drop- down field we can choose different body types well we'll leave the default which is Json now we need to type a Json object here so inside curly brackets uh let's add a field here which needs to be inside double codes so for example the name field which is equals to A String so double codes again and inside for example I'll put node.js course and let's add another field so comma and the next field will be the price okay which is equals to 97. 99 okay perfect so let's click on send and great we got a success response now back on vs code here is the Json body we just sent from Postman with the name and the price now we can manipulate this data inside the route to insert or update our database awesome so before we proceed uh let's install module that will'll watch for changes on our code and stop and restart the server for us because every time we need to test something we have to open the terminal stop and start the server Again by typing node index.js so the module or dependency is called nodemon and it's going to be a development dependency so let me stop the server here and type npm install node mod and let's add the development flag here which is D- save-dev hit enter and great now if we check here inside our package Json file we'll see that nodemon is under the dev dependencies object that means that when we add this project in production only the dependencies object will be installed and not the dev dependencies these are just for development purposes now to configure nodemon as you can see we have an object here called Script uh we can get rid of this test script here and let's add another script to handle noemon uh I'll call start and and the commment instead of node index.js we're going to type nodon index.js and to run this script uh let's go back to the terminal let me clear this and the commment will be npm start hit enter and nodemon will restart the server for us every time we save a file so let's test nodemon here on the index.js file inside our route I'll change the response message to hello world now when I save this file here on the terminal nodemon will restart the server for us and back on Postman uh I'll just click on send and there we go we got the hello world response message so noemon is working perfectly and we can even close the terminal for now perfect now we can actually connect mongus to our cluster we created earlier so below the express Json configuration I'm going to call the module so mongus do connect and the first parameter here is going to be the URI that means the connection string that connection string we can get it on the mongod DB Atlas dashboard so let's go back to the website I'll click on the connect button and select the drivers option and as you can see the first drop down here is the technology we're using uh I'll leave as the default which is no JS and the next drop down is the version of the driver and I'll leave the latest as it is so the example mongodb Atlas is showing here is using the mongodb module directly and not mongus but the connection string is the same for both these modules so let's copy this connection string by clicking on the copy icon and back on vs code let's space the connection string inside the mongus connect function and we can remove these configurations on the end of the URI after the last slash CU we won't use it now we need to change the p password placeholder here to the password we created which is manfra 23 if you notice this is the same connection string we used on Compass so this connection string is to connect to our cluster a cluster can have multiple databases so we need to specify a database here on the connection string if this database doesn't exist so mongus will create for us we can specify the name of the database after the last slash here so let's call our database iore API perfect so we didn't create this database on Compass or directly on Atlas dashboard so will create for us now we can specify an event on to check if the connection was successful or if there is an error to add events on uh we can call the module do connection do on and the first parameter is the name of the event and it's a string so I'll add here connected and the second parameter is a call back function so if the connection is successful let's add a message on the console so console.log and in here I'll just put mongus connected okay and our server will only start if connection is successful so I'll cut the express. listen and I'll paste inside the call back function of the success event okay okay perfect now we need to create another event if there's an error in the connection so right below the success event I'll add another one so mongus do connection Doon and the name of the event is error and the second parameter is also a call back function so let me put here the arrow function but now it will return an error object so let me put error here as a parameter and inside this function I'll write a message on the console so console.log and I'll just put mongus connection error and column and a comma here with the error object okay perfect so let's test our connection and I'll open the terminal again and when I save this file node modon should restart the server for us and we should see some message on the console if it was success or not so contrl s to save and there it is connected and the server was started successful as well so the connection between mongus and mongod DB Atlas is complete now let's simulate an error here to see if the error event will be fired so here in the connection string I'll change the password and I'll remove the three here on the end and save okay so now we got the complete eror object here showing what went wrong with the connection and here on the top is the mongus connection eror message saying authentication failed great so both events are working and let me change the password here to the correct one save and everything is working again great so we create a new database called myor API and we need to create a collection for this database so let me just close the terminal here and with mongus we can create something called schema which defines the structure and property of a document inside the collection so comparing with the SQL database collection is the same as a table and a document is the same as a role inside that table so all schema files will create uh inside a directory called models model is a wrapper on the schema so let's create this directory inside the root uh right click new folder and we'll call this models and inside this folder let's create a new file with the name of our first collection which is product. Js so it's a good practice to name all model files starting with an uppercase and we'll see the reason for this further on the video so inside this file we specify the fields that our document will have like name of the product price description quantity and others so let's start by an importing module on the top so cost equals to required mongus next we'll Define our schema so const product schema equals to new mongus do schema okay so this is a function and inside we'll have an object with the fields and their types so the first field will add is the name and name will receive an object with some options here and the first option is going to be the type and it's going to be equals to string and this will be a required field so the next option we'll put here required true and by default required is always false so let's add another field or property and after the name object I'll add a comma and this one is going to be description and description will also receive an object with the type option and it's also going to be a string and this is not a required field so we'll just leave the type option here and since we don't have any other options we can remove the object and put string directly here okay perfect so comma and the next field is going to be the price and price is going to receive an object with the type as number and number can be a flow to decimal uh we can use for integer as well but we might need to add some validation here so let's leave as number and this is also going to be required so required true okay so let's add another f field here and the next one is going to be the quantity like the quantity we have in stock and this one will receive an object and the type I'm going to put as number as well but there is a big end option here okay so I'm just going to leave as number for standard and we have a default option here which is the default value if we don't pass this field when inserting a product okay so for the default option I'll put zero here so we won't have no values for the ity only zero okay so let's add one more field and this one is going to be the active field if we're still working with this product or not okay so this is going to receive an object and the type it's going to be a bullan field okay so only true or false and the default for this field is going to be true okay so if we don't pass the active it's going to be true so let's add another field which is the category and this this one is going to receive the object as well with the type as string and this is also required so required equals to true and we're going to have different types of categories like Electronics courses books maybe so for this field we're going to add Anon option the Anon validator is an array that will check if the value given is an item of this array so Anon will receive an array and we're going to add the categories here in side since the category property type is a string so the items inside the array should be a string as well so the first category is going to be electronics and the next one is going to be books and let's add a third one here which is going to be accessories perfect okay so this is how we Define a an un validator here for the category field okay I think we have enough Fields here to work with so all fields are defined inside the product schema object now we need to export this schema so we can add on our database and also use in other files so here on the bottom let's add module. exports equals 2 and to export this we're going to put mongus do model and this is a function that will have two parameters the first parameter is the name of the collection and the second is the product scale SCH that we created here on the top so the collection name is product with capital P or not it doesn't matter and the second parameter is the product schema so we are attributing to the product collection the product schema that we Define it here perfect so now it's time to use this schema and insert read update and delete products on our database uh we'll create different routes to do all this crud operations so let's open the index .js file and let me remove these blank spaces here okay now on the post route we already have let's use this route to receive data from the client and insert into the product's collection so let's rename this route to instead of being just slash we're going to put the resource name which is products and as I explained on the rest API video we can put products on plural or not it's up to you just make sure to use the same for all routes so the post method on the route is usually used to insert data into a resource in our case is the product and we're going to use the product schema to do that so let's import the product schema which is inside the product. JS file here on the top so cost product with a capital P equals to require so the index.js file is on the rout so we need to access the models folder okay to do that we're going to put dot slash and we have access to everything on the route so models slash product perfect now inside the post route We'll add the data from the request body that the client will send into the product collection so let me select all the code that we have inside the route and we can remove it okay so to create or insert a new product let's call the product schema here so product. create function and inside with we have to send a Json object with the same fields we defined on the schema file we can get this Json object on the request object of the route that the client will send to us so let's add here request. body okay the create function returns a promise so if everything worked we can add a DOT here then and this returns a call back function with a parameter which is the new product object we just created so let's add a arrow function here with the new product object as a parameter and let's return this new product object to the client calling the response object so inside the function uh return response. status and we'll add the status 20 101 which means created whenever we create something on the back end it's a good practice to send 21 status code and we're going to also send a Json response with the new object we just created let me copy and paste here inside perfect now if something went wrong we can add a DOT here catch which also returns a call back function so Arrow function here but this time the parameter is going to be an error object so in this case we'll return to the client the response do status 500 which means a server internal error uh with a Json response with the error message so error equals to the error object of the function. message okay so the create product post route is done for now so let's test on Postman and here in the URL field I'll just add the slash products and here on the Json body object uh I'll leave the name as it is and the price as well and let's check on the product schema the rest of the fields we defined and we have the description field so below the name field I'll add description and for example I'll just put here node course description or just for example and back on the schema uh the price is right here on the body so comma and the next field is the quantity so quantity and I'll put 10 here okay the next is the active field and by default is already true but I'll add it on the body anyway so active true and the next field is the category and it have to be one of these three options here so category and since this is a course uh I'll put on the book category okay all fields are on the body and let's click on send and perfect we got the new product as a response with all the details we Define and not that created two new foods here for us uh one is the ID which is a unique field that acts as a primary key of the document so by default uh if we don't specify this field on the schema creates automatically for us and the type is not as Str as it looks it's a object ID type uh we'll see later on the video how to validate this uh just know that for every collection or or table if you're using a SQL database we must Define a primary key and already does this for us and the second field is the underscore uncore V which means version key uh it describes the internal revision of a document by default it's zero and it only increments when an array inside the document is updated we're not going to use this field so we can't just ignore it and we also can configure on mongus to exclude this field from the collection but we'll just leave as it is now let's check on Compass to see if our database is created here on the top we can click on the options and reload data to refresh and here's the my API database if we expand this here's the products collection and the document inside just like the response we got on Postman perfect so everything is working our post route is working now on the M good schema we can configure lots of things and a very good practice is is to always save the date and time of the document when it was created or last updated as well but we don't need to Define these fields manually there's an option on mongus that we can configure and mongus will create these fields for us automatically so after the fields definition uh we can add another object and there's an option called time stamps which is false by default but if we put as true will create the cre date ad and the update ad field and will also fill in these fields when we insert or update a document so now that we added the Tim stamp option as true let's create another product on Postman to see what happens so for the name here I'll just change to JavaScript course and the description I'll just put Javascript course description the price is going to be 5099 I'll leave the quantity the active and the care category as it is and let's click on send awesome here's the new product object with all the details we entered and here are the created ad and the updated ad Fields both with the same date and time so the create will never change unless we change manually and the updated ad will only change when we update a product perfect let's check on Compass so we can click here on the find button to refresh the data and here here's the new product with the time stamps field note that the first product doesn't have these fields because we created before adding the timestamp configuration on the schema so the timestamp configuration is working uh let's go back on the post route to change a few things here so we're handling the responses inside the call back function of the gr method but we can change this route to be a synchronous that means we'll call the create method and we're going to wait till it finish and then depending on the result we can return a success response or catch the error to return the error response so let's do that right now I'll add some Extra Spaces here and to make this function asynchronous uh before the function we need to add the async word here right before the request and response parameters now inside the route function we need to add a try and a catch block here the catch block will have an eror object as a parameter so it will try TR to create the product if something goes wrong it will fall into the catch block here so what we can do is grab the ero response we already added here on the create catch callback and paste inside the catch of the route function now inside the triy block we're going to create our product and for that uh we'll start a new product object inside a constant so const and I'll call new product as well just like the one we already had and since this is a asynchronous function we need to wait for the promis result of a function in our case the create function so we need to add the await word before the promises and then product. create with the request. body just like we added before and if everything works and then we can return a success response so I'll just grab the success response we already have over here and pay right below the constant new product and now we can get rid of all this piece of code here so this is how a sync and a weade methods work we should handle as synchronous functions inside a tri catch block uh we're not going to get deep into a synchronous or promises explanations uh we're going to use this in all routes of our API so we'll get more and more familiar with this let's just make sure everything's working back on Postman let's create another product so I'll just change the name here to laptop and the description to laptop description the price to 400 the quantity to four and I'm going to remove the active here since it's already True by default and the category is electronics click on send and here's the laptop product details uh know that the active is true here by default and know the ID as well so everything is good now back on Compass let's click on find and here's the new laptop product so the async and a weit we added on the route is working perfectly now back on Postman the name field we added on the product schema is required so let's see what happens if we remove the name field from the body object and click on send we we got a status code of 500 and amongus error message saying product validation failed so we need to send a better response to the client with the correct status code uh back on the post route uh let's add validations to all required Fields so above the create method on the con new product uh I'll add a ni statement checking if the request. body. name is undefined by adding an ex clamation sign on the beginning so if the name inside the request body is not there let's return a response to the client so return response. status and the code for this it can be 422 which means unprocessable entity and every time the client send invalid data to the back end we can return this code and also a Json response with an error message inside the object so eror and the message will be name field is required great since we had the return word here before the response so the rest of the code won't be executed back on Postman if we try to send the body object now we got a status code of 422 and the error message saying name is required so our validation is working now let's check here on the product schema all fields we Define as required so besides the name we add the price and the category as well so we need to add validation for both of these fields so back on the post route I'm just going to copy the if statement we added for the name and I'm just going to paste below here and I'm going to change the name here to price and the same for the error message inside the response so price field is required and we need to add the validation for the category as well so I'm just going to copy this one again and and paste right below now price becomes category and for the error message category field is required so let's test these new validations on Postman and we already test the name field so I'll put the name back here and I'll type laptop comma and let's remove the price now okay let's click on send and great we got the 422 and price field is required so let's add the price back again and let's remove the category field okay uh click on send again same thing 422 category field is required So Perfect all the validations from the post route is working and let me add the category field back here and on the product schema we Define some categories inside the an non validator so the category have to be one of these three options we added inside the array so on Postman if we try to add a different category here let's say food which is not on the list and we click on send again we got a 500 status code and eror message from mongus so we should definitely add a validation for this as well and send the correct response to the client so back on the post R let's check if the client is saying in a category that's not on the Anon array so this first if statement is checking if the category is not defined on the body if it is we can add a else if statement here so else if and now we need to grab the categories in the non array and check if the category that is defined on the request body doesn't exist on the array so I'll add a exclamation sign here and to get the array of categories available we can call the products schema do schema do path and inside the path method we have to add the category field the scheme schema. path can be used to inspect the schema type and validator for a given path or field in this case the category and it returns information from the schema so after the path here we can add a DOT and none values in camo case so this line of code here uh we return the array we defining the a none inside the category field in the product schema so since this is an array uh we can add a DOT includes here uh the includes method checks if an array includes a certain value among the entries returning true or false so we need to add here the category inside the request body uh I'll just copy here and paste inside the includes method so we can read this else if statement as if the category in the request body is not included on the Aon array and then we need to return the correct response to the client so let me copy the response we have up here and let me paste inside the lcf statement the 422 will be the same but let's change this error response message here it's a good practice to always send the response containing complete information to the client so I'll add back tick here and we can send the categories available in the response so the client knows which categories it can send so let's send a message here for example category uh must be one of these options and let's put the dollar sign here and the curly brackets and now we can send a list of categories that the client is allowed to send so let me copy the piece of code that Returns the categories and non array and paste inside the curly bracket here perfect but this will return an array inside the message uh what we can do here is put a dot join and the join method returns a string by concatenating all elements of an array uh separated by specific separator string so join takes only one parameter which is the separator so let's add a comma here and a blank space great so let's see how this response message will look on the client back on Postman so the category here I'll leave as food and click on send and perfect here's the status code 422 with the message category must be one of these options Electronics books accessories now the client knows which categories it can send so let's change here from food to electronics and click on send and perfect we got status quo 2011 and the new product here with all the details and let's check on Compass so we have three products but if we click on find now we have four and here's the new laptop product and actually we have a duplicate product here but with different IDs we could add more validations here on the post route but that depends on your rest API architecture it's very important to send a complete response to the client informing what it have to do next in case there's a validation error perfect so we have an endpoint to create a new product and we are checking on Compass all products Rec created but we need an endpoint to get all products recreated so let's create a new route here below the post route so app Dot and now it's going to be a get route and the name of this route will also be slash products just like the post route we created the name of the route should always refer to the resource and the G Route will also be a synchronous so async and the same parameters here the request and the response and let's add a arrow function here okay and now we need to add the try and the catch block here so try and the catch here with the eror object as a parameter we're going to add the tri catch block to all async routes and in inside the catch block will'll always have the same response returning 500 as the status code and the error message as well so let me copy the one that we already have here on the post route and let's past here on the get route okay now inside the triy block or we're going to get all products and return to the client to do so let's create a new cost that will hold all products as an array so cost product equals to a weight because this will return a promise the product schema Dot and we're going to use the finded method here the F method is used to fetch data from The Collection uh in a SQL database it's similar to the select command uh we can add a filter inside as a parameter to fetch a particular object but in this case we want to fetch all products so we don't need a filter here and we can live without a parameter great so defined method return an array and all we need to do is return to the client so return response and the status code we're going to put 200 here which means okay and it's the default code if we don't specify a status code on the response and we're also going to send a Json response and inside we're just going to put the products cost that we created holding all products okay perfect so this route is ready to test we can go back to postman and let's open a new tab here by clicking on the plus sign to open a new request and let's copy the URL from the post and point we already have and it's going to be the same URL but it's a get method now so we'll paste here and we can click directly on send and perfect we got the 200 status code okay and the array containing all products recreated with all Fields inside the objects great so our get route is working work but we can actually specify the fields we want to return so inside the get route after the fine method we can add a DOT here and there's a method called select select is a method of mongus that is used to select document fields that are to be returned in the result so we can specify the fields separate by a wi space inside a string so let's say we want to return the ID the name and the price okay all separate by a white space here and let's test to see how it looks on Postman so we can click directly on send and here it is uh the objects now have the ID the name and the price just like we specified on the select and we can also exclude a field from the object all we have to do is add a dash or a minus sign in front of the field name so for example we don't want to send the version key field so we can put a dashcore corv here so now we are removing the version key from the result query here let's test on Postman click on send and now we have all Fields inside the products object except the version keyfield awesome let's leave the response like this now what if the client wants to get details from a specific product so it might need to send a parameter which usually is the primary key or a field that is unique for each product so we can fetch that particular product by that unique field in our case we can use the ID field which is the primary key and it's Unique for each product so let's create a new route here that going to return only a specific product to the client so below the get all products route app Dot and it's going to be also a get route and the name is the same so slash products but this time the client needs to send a parameter which is going to be the ID of the product and to configure parameters in a URL we can put a slash here column and the name of the parameter which is ID and we're going to see soon how to handle the parameter from the URL and this will be a synchronous as well so async with the same parameters uh the request and the response and arrow function here and inside just like the other routes uh we're going to put the try and the catch block here as well and the catch block with the eror object and we're going to copy the same EO response that we are using in other routes and paste on the catch block of this new route now similar to the get all products route we're going to create a constant that's going to hold this specific product object that the client request so cost product and this will be an object and it's equals to a weight because it's going to return a promise the product schema now here's the reason why the schema name here should be be capitalized because we're stenting the con called Product so the product schema should be upper C case and the cost or variable that is the instance of the product schema should be the same name but in lower C case great so here on the product schema do and to get a product by its ID there's a method here on which is called find by ID and as the name already says it's a function used to find one document by the ID it returns an object with details of a document in our case the product and for the parameter here it's the product ID which we're going to get from the parameter on the URL and to get the ID parameter uh we can call the request object Dot params and if we put a dot here it's going to show all parameters we Define in our case just the ID parameter same as the parameter in the URL great now all we have to do is return the specific specific product to the client so return response. status and the code is 200 okay and the Jason response it's the product cost we Define up here let's test this new route on Postman and let's grab an ID here of one of the products the node.js course here for example let's open a new request and the URL will be the product URL but we'll add a lash here on the end and pay the node.js course ID here now let's click on send and perfect here's the 200 okay status code and all the details from the node.js course so everything is working with our new route and note that the finded by ID method it's similar to the Fine method that we use on the previous route that means we can also add a DOT select here to select the fields we need so let's do exactly like we did before let's remove the version key field and let's test on post Postman but let me get the ID of another product here to test uh let's get the JavaScript course ID and let's paste here on the URL parameter click on send and perfect so we got the JavaScript course object here with all the details except the version key field so the select function is working as well on this new route now what if the client send an ID that doesn't exist so for example I'll change the last chart here to zero click on send and we got 200 status quote okay but we got n on the response so we definitely had to handle a better response to the client so what we need to do here is just check if the constant product that we Define here is null so I'll add an if statement and I'll put the exclamation sign and the product constant so if the product constant is not there and then we can return response. status and we can use the 404 status code which means not found and also adjacent response as well with an error saying product not found okay very simple let's check on Postman I'll just click on send and perfect we got the 404 not found status code and the AER message product not found so our validation is working perfectly now the ID on it's not a string it's an object ID type it's a 12 byte object ID and it consists of a 4 byte time stamp app representing the objects ID's creation a five byte random value generate once per process and a three bite incrementing counter initialized to a random value that means that the object ID has its own format and if the client try to send a different format for the ID parameter here so let's say 1 2 three and click on send then we got an mongus error saying cast to object ID is invalid so we also should handle a better response here for the client with the correct status code as well so inside the route before defined by ID function we need to check if the ID parameter the client is sending is a valid object ID so let's add an if statement here and offers a function to check if the object ID is valid so mongus dot and the function is called is valid object ID and for the parameter uh we can pass the request. params do ID and the is valid object ID function returns true if can cast the given value to an object ID or false otherwise so what we can do is add an exclamation sign here on the beginning of the if statement and now if it's not a valid object ID the ID parameter and then we need to send the response to the client so return response do status and here we're going to use the 422 unprocessable entity status code because the client is sending an invalid data which is the ID and we're also going to send Json error so inside the object here uh just put error and the message will be parameter is not a valid ID okay so let's check on Postman uh I'll just leave one two three click on send and we got the correct status code 422 and the error parameter is not a valid ID perfect so now the client actually understand what's going on so let me put back here the JavaScript course ID and click on Sand and great so all validation is working perfectly inside the get product by ID route so we already have a route to create a product to get all products and to get a specific product by ID and we need a route to update details of an existing product let's create this new route below the previous route so app Dot and and we'll use the put method here uh which is used to update an existing resource in our case the product and the name of this route is also going to be slash products and since it's going to update a specific product so we'll also need the ID parameter here on the URL just like on the previous route we created and this put route will also be a synchronous so as sync with the request and the response parameters the arrow function just like all routes we created we're going to add the try and the catch block here as well and we're going to copy the error response that we're using and paste on this new route okay perfect now inside the tri block since we're expecting an ID from the client let's cop the object ID validation we used on the previous route and paste inside the put route so copy in here and paste in the tri block okay perfect so now we're validating the ID on the parameter so what we can do here is store in a constant the details of the updated product and send back to the client the updated product object so cost product updated and it's going to be equals to A wait because we're expecting a promise here and the product schema and let me scroll up here a little and Dot and we're going to use a function called find by ID and update the find by ID and update function it simply grabs the document by matching a particular ID and update the data inside the document that the client send on the request body and for the parameters first it expects the ID of the resource which is the ID that we're validating here and we can get it from the request. params doid and the second parameter is the object data containing the fields to update and and that we can get it from the requestbody just like we use on the post route to create a product great now all we need to do is return a response to the client with the product updated constant that we created so return response. status and this is going to be a 200 status code as well with the Json response containing the product update cons we created here so product updated okay let's test on post and let's update some details here of the JavaScript course product that we have here so what we can do is copy this entire URL containing the ID as a parameter open a new request and paste on the URL field and we need to change the method here from get to put and now we need to send a body on the request so body Tab and we're going to choose the raw option here and select the Json type here on the dropdown okay now we need to type an object here with the details that we want to update so for example let's update the quantity here which is 10 so back on the put request inside the object We'll add the quantity here and we're going to update to five click on S and great we got 200 status code but the quantity here on the response is still 10 let's check on the product ID request tab the JavaScript course ID is right here click on send and the quantity is five so that means the product was updated so here on the put end point response we are getting the old product object before we update it and to return the updated product object we need to add a configuration here on the finded by ID and update function so after the requestbody we can add an object here and there's an option called new which is false by default so we need to change it to True okay let's make sure this is working back on Postman uh let's update the quantity now to eight and click on 10 and perfect the quantity on the response object is eight so we are getting the updated product object now let's add another field here on the object to update so for example the price and now it's going to be 54.99 and click on send great we got the correct updated price and the quantity which was already now let's add a invalid object ID here on the parameter to check if our validation is working so click on send and we got the correct status code with the error message and let's add an ID that doesn't exist I'll put back the JavaScript course ID and change the last character here and click on send and we got new on the response and the status quod 200 okay so we should return a better response here so inside the route before we call defined by ID and update function we should check if a product exists matching the ID on the request parameter so let's add a if statement here and we're going to call a function that returns a promise and we can add the a weight directly inside the if statement and we're going to call the product schema Dot and there's a function called exists and inside uh we can add an object with a filter so we can put something like underscore ID column and the ID parameter so request. prams do ID the exess function returns true if at least one document exists in the database that matches the given filter and false otherwise we can add an exclamation sign here on the beginning of the if statement to deny all this so if the product doesn't exist matching the ID field with the request ID parameter then we can copy the response from the validation inside the find product by ID route and post inside this if statement great uh let's test this validation on Postman and we already have here on the URL parameter an ID that doesn't exist so just click on send and perfect we got the correct response with the error message saying product not found so the validation is working now let's update a different product uh I'll open the get all products tab here and let me click on send again to fetch all products and let's update the no JF scores here let me copy the ID here open the update Tab and let's paste the ID on the URL parameter and let's update the description field for example to a book about building projects with node js Express and mongod DB okay and let's update instead of the price the active field so current it's true let's update to false Okay click on send and perfect we got status quod 200 okay and the object details updated here uh with the new description the active as false and not that now we got an updated ad filled with the update Tim stamp let's open the get all products tab click on send and here's the nodejs product updated uh the description the active and the updated at awesome so the updated point is complete and we could add more validations here let's say if the client is going to update the category so we can add the validation we added on the post route to create a product and we learned the exist function and if we put the cursor on top of the function the return here is not true or false it actually Returns the ID of the document if it matches the filter and no otherwise uh we could use the finded by ID method as well on the validation but for learning purposes we use the exist function which also works so just recapping we have endpoints to create product get all products get product by ID and a data product by ID so now all we need to complete the crude example is the delete endpoint so let's create below the put route here so app Dot and we're going to use the delete method the name is also slash products and just like the update and get by ID routes we're going to delete a specific product so we need the ID parameter here as well and also async and the request and response parameters and the arrow function inside the function the try and catch block and we're already familiar with this let's copy our default errow response and paste on the catch block inside the tri block since we are expecting an object ID on the request parameter let's copy the validation we already have checking if the ID is valid and next since we are deleting a product we don't need to send the product on the response for the client because it doesn't exist anymore so first let's type here await and call the product schema Dot and now we're going to use uh the find by ID and delete function which is used to find a matching document removes it and passing the found document if there is any to the call back and for the parameter here it expects the product ID and we can get it from the request. pm. ID and let's return a response to the client so return response. status and here we're going to put the 204 no content status code this status code means that the request was successful but there's nothing to send back because the resource SCE is not there anymore and we can put dot here and send okay the thead route is ready to test so let's go back on Postman and let's open a new request tab here and the URL is going to be the same we are using so Local Host 3000 SL products and we need to change the method here from get to delete okay now we need an ID here to pass on the parameter so slash and and let me open the get all products tab here and let's grab a product ID to delete so since we have two laptops here uh let's delete one of them let's copy the ID from this second one here and let's open the delete request Tab and let's paste the laptop ID here on the URL parameter let's click on send and great we got the 204 no content status code and there is no response on the body here so the client knows that the delete was successful by the the status code okay let's check if the laptop was deleted so open the get all products Tab and the latest response here we have two laptops so click on send and now we have just one so the delete end point is working perfectly back on the delete request tab Let's test some validations here I'll change the ID parameter to an invalid ID so 1 two 3 and click on send and great we got the 422 status code and the message saying the ID is invalid now let's change back here to the laptop ID and I'll change the last character to zero so this ID doesn't exist let's check the response so click on send and we still got the 204 no content status code and the empty response body but nothing was delete because this product ID doesn't exist if we check on the ghetto products tab all products still there so we should definitely inform the client that the product ID it's trying to delete doesn't exist so on the delete lead route uh we could use the exist function we used on the put route to check if the product exists but for learning proposes let's use something different what you're going to do here is get the product object by using the finded by ID method and store on a constant and if the product const is not nle that means the product exists so we'll delete the product inside the constant let's see how this works so below the ID validation here let's create a new cost and product and it's equals to await the product schema do find by ID we are already familiar with this function because we use on the get product by ID route actually let me copy the code we have here without the select function and let me replace this one here okay so we are getting the product by the ID on the request parameter next we'll add an if statement checking if the product constant is null so exclamation sign and the product constant so if it's null that means the product doesn't exist so we can return the correct response to the client and we already have this response here as well so let's copy it from the put route and paste inside this if statement okay so if the product doesn't exist we are returning the correct message with the 404 status code now if the product does exist so let's add an lse statement here for the if and what we could do is cut the find by ID and delete function here and paste inside this L statement this will work normally but since we already have the product cost so we can get rid of this here and we can use this product cost here inside the L statement because this is an instance of the product schema so we have some options inside that we can use so inside the L here uh I'll call the8 and the product con with the instance of the product schema and if we put a dot here it will show a list of options that we can do with this product here and there's an option called delete one the delete one method deletes the document that is stor inside our product constant that we got from defined by ID method so there are different ways we can delete a document and this is one way to check first if the product exists and then delete that document if it does exist let's test these changes on Postman so in the delete end point URL we already have an ID here that doesn't exist so let's click on send and great we got the correct response with the 404 status code and the error message saying product not found now here on the get all products request tab let's get another product ID to delete so let me copy the ID of the other laptop product here and let me paste on the delete endpoint URL click on send and perfect we got the 204 status quod that means the product exists this and it was deleted let's open the ghetto products request tab just to make sure the laptop was deleted so as you can see this is the old response and if we click on send great the laptop is not there anymore and we only have two products now awesome so we completed our recruit application and we have any points to create read update and delete products from our database but we Define all these routes inside our index.js file and in the future let's say we'll have endpoints to manipulate other resources as well so the index.js file might get messy and too big so we should remove all these routes from the index file and add in other files the index file should only contain configurations from our application like Express the mongodb connection and the server creation so let's add these routes inside a route file here on the route uh let's create a new folder call route and we'll store the product route in a separate file inside this folder so right click new file and we'll call this file product route. JS okay perfect and let's copy all routes we have inside the index.js file from the delete to the first one which is the post route okay let's cut it from here and let's paste inside our product route. JS file now we need to change some things here uh we don't have the app constant in this file so we're going to replace with an Express router function so here on the top let's import the router function so con router equals to require Express and here on the end do router function so we are extracting the router function from inside the express module okay now we need to replace all app constants we have to the router we just imported so I'll open the find Dialogue on vs code and we're going to find for app and replace with the router and click on the replace all button here okay so everything replace it and we can close this dialogue now we need to export these router function so we can use in other files so here on the bottom I'll type module. exports equals to router now we can use the products route file inside other files and on the index.js file we need to initialize the product route file so we'll do that right below the mongus connection functions so app. use and in here we're going to requir so the index.js file is on the rout and we need to access the product route file from inside the routes folder so inside the required we can put dot slash and we have access to everything on the route so routes folder and products route file okay so the routes are almost ready to use but we still need to get the product schema import here from the top cut and paste on the products route file below the router import but we need to change the path here on the product schema required so the product route file is in inside the routes folder and we need to go back one folder and get the product schema file inside the modules folder so here on the required uh to go back one folder we can put a dot dot slash and now we're on the route so models slash the product schema file great so let's test these changes here uh let me save the index.js file here and back on Postman let's call the get all products endpoint click on send and perfect we got all products let's grab the ID of the nodejs course here and paste on the URL of the get product by ID and point click on send and oh we got an error here oh I forgot to import the mongus module on the products route file so let me open the products route actually let's copy the import here from the index file and paste before the product schema import on the product route file okay because we are using the mongus module to valid dat the object ID here so let's check on Postman again we'll just click on send and perfect we got the details for the node.js course awesome so our routes are working again in a separate file now but we could improve this code a little bit more uh what we can do is separate the content we have inside the routes to a different file leaving all logic inside the routes separate from the routes declaration we should add these logic inside functions that the name of the function already tells us what it does like create product get all products get product by ID and so on so we'll start these functions inside a file called Product controller which will be inside a folder called controllers so here on the root let's create a folder called controllers and inside a new file called products controller.js so inside the products controller file we'll add all the content from inside the routes we have here everything after the name of the route including the request and response parameters and let's start by copying the mongus and product schema Imports here on the top and paste on the top of the product controller file now we'll create the functions here containing the logic inside the route so we need to export all functions so we can use in the products route file instead of putting module. exports on the end of the file we can put here export Dot and we can declare the function directly here that way the function is already being exported and we can use in other files so the first function will be create product in camo case which is equals to this will be an asynchronous function so async and the arrow function and now we'll copy everything from the create product post route uh everything inside the arrow function and including the request and response parameters we can cut from here and paste inside the create product Arrow function after the async okay so all the logic is in the controller file and we have to import this file inside the products route file so I'll select the mongus and product schema Imports and replace with cost product controller equals to require and we need to go go inside the controllers folder so dot do/ controllers SL products controller now inside the post route uh we can remove this async here and call the products controller. create product great so we're going to do this for all routes here so the next route we'll be changing is the get all products routee so I'll copy everything including the async so cut and let's paste inside the products controller so so we'll create another function exports and this one is going to be get all products uh which is equals to and we're going to past here okay now inside the products route file inside the get products route we're going to call the product controller and let me just add the product here as a plural on the import and on the post route and on the get route to be exactly as the name of the file so back on the get route Dot and we're going to call the get all product function okay now let's copy the entire code from inside the get product by ID route and let's create a new function here so export and this one is get product buy ID equals to and we're going to past right here okay now we're going to do the same thing back on the route uh we're going to put product controller. getet product by ID okay same thing for the put r copy everything back on the products controller export and this one is update product and we can put here buy ID if you want because we're updating the product passing the ID on the parameter and we can put here EOS and we're going to paste the content here now inside the products route file inside the put route we're going to call product controller. update product by ID now for the last route which is a delete route copy everything and on the controller file export and this will be delete product and we can put by ID as well and equals and we're going to paste the content here okay uh back on the products route we're just going to call here product controller. delete product by ID awesome uh let me just remove these blank lines here between the routees perfect uh we separate all logic from the routes file and put inside the controller file and as you can see the routes file are totally clean and we can understand what each of these routes does by looking on the name of the function so we know that we have a route to create to get products update and delete products now let's test all this on Postman we'll start by the get all products route click on send and perfect it's working let's create a new product and this one is going to be an adapter and for the description uh let me copy the adapter and paste here adapter description the price will be 20 and we have 10 of these in stock and the category is going to be accessories okay great so I'm not going to put the active here since it's true by default click on send and perfect we got the new product details here on the response body now let's update this product so I'll copy the ID here on the response and open the put request tab replace here the ID and the Json body let's remove this description here and update the active to false perfect we got the updated details on the response now let me copy the ID here on the parameter and let's delete this product here okay we got 204 no content and let's get all products again so we have two here and let's click on send and we still got two products because we delete the adapter product before calling the get all products handpoint so everything is working perfectly and our code is complete organized if we want to create endpoints for other resources we can just add a route file and a controller file for that new resource and let's do this now actually uh the category here inside the product schema is defined by Nan with only three options but what if the client wants to create its own categories or delete a category that it doesn't use anymore or get all products by category so let's create endpoints to manipulate the category as well and we'll create a collection for the categories on the database so let's define a new schema file for the categories uh on the models folder let's create a new file called category. JS with a Capital C and let's open the product schema file and select everything here copy and let's paste inside the category JS schema file and let's change the schema name name here to category schema and also here on the bottom let's change the collection name to category and let's replace the product schema to category schema now the fields uh we can select all Fields here and leave just the name field and remove the rest we'll only need the name field and the created and updated ad Fields so we can leave the timestamps as true now on the product schema file we're going to create a relation between between products and categories through the category field here so instead of saving the category name we're going to save the category ID so let's remove everything here inside the category object so select everything and delete and the category type now is going to be an object ID and we can get it from the module so do schema dot types and object ID since the object ID type is a special type we need to get it from inside schema types different from the string number the other types we are using here and still inside the category object uh we need to add an option to refer that it's related to the categories collection here so inside the category object this option is called ref and it's a string and it takes the name of the collection that we are relating to in this case the category with a Capital C and it's still required so we're going to put required as true okay so we create a relation between the category field in the products schema to the categories schema now just like for the products we're going to create a route file for the categories so inside the routes folder new file and we'll name this categories route. JS and we'll also create a controllers file so inside the controller folder new file category controller.js and to win some time here what we can do is select the entire code from the products controller file copy and inside the categories controller let me just close the Explorer here and paste the content inside here perfect now let's replace the product schema to category and inside the required as well category okay perfect now we need to change the functions here from product to category so create category and inside the function here uh the validation is okay we can leave the name but we won't have the price and the category so we can remove these validations here and the cons here will be new category and the 08 here is going to be category and create okay and on the response we need to change the Json here to New category okay so this one looks good now the get all products will be get all categories and the cons here will be categories and await the category schema okay fine select we don't need the version key as well and on the response I'll just copy here and paste it on the Json okay and the next is the get product by ID and actually we don't need a get category by ID uh you can create one if you need but I don't see the point here so we can remove this one and the next one is the update product by ID will become update category by ID and we can leave the object ID validation here on the top and this product schema will be category because we're validating if the category is found so category not found and the cons here will change category updated and the product here will become category fine by ID and update and all the rest is good just the Json response will be category updated the next one is the delete product by ID will become delete category by ID okay we'll leave the ID validation here on the top this cost here becomes category and the product category as well find by ID and we'll change all products instance here to category okay and category not found and category here delete one and the rest is good okay so we basically change everything from product to category and now we have crude functions for the categories as well and now all we need to do is create the routes for the categories and same thing to win some time let's copy all routes inside the products route file and paste inside the categories route file and products controller will become categories controller and we need to change on the require as well so categories controller here now we need to change all the these routes here and replace slash products to slash categories and call the functions from the categories controller so I'll just forward the video to win some time okay so we have all the routes here for the categories as well except the get category by ID and we need to import this categories route file inside the index.js file so let me copy the import here for the product route file paste below and change to categories route great now let's test all categories end points on Postman now Note One Thing uh if we call the get all products endpoint you can see that the category field here has been deleted for all products that's because we changed the category type on the product schema so if you're doing this in production make sure to do a backup of the database before applying these changes let's actually clean all products we have on the database let me open compass here and let's click on find to refresh the data and delete each of these products here perfect so the product collection is empty and let's click on the options button here on the top reload data and here's the new categories collection we created on mongus so when nodemon restart our server after we save the changes mongus creates this new collection based on the new category schema file so now we have two collections here now back on Postman if we call the get all products end point and click on send we got 200 status code okay and an empty array and that's how the response should be now let's organize thanks here on Postman uh we can save all these requests here on a postman collection so on the left side here we have the collections option open and to create a new collection we can click on the plus sign here on the top and and choose blank collection and on the name field here on the top we can type the name of our collection so let's put my API in Upper camo case great so the collection is created now we can save all endpoints inside my API collection so let's start with the post request here and click on Save here on the top and on the dialogue select my API collection click on Save and now the post request is saved in my API collection ction we can click on the options here to rename so rename and we'll call this one create product now for the get all products request let's open here the tab and we're going to click on Save and my API is already selected let's change the request name here on the top to get all products Okay click on Save great you can see how it looks more organized here now let's let's do it for the get product by ID click on Save and we'll change the request name here to get product by ID and click on Save okay now for the update request click on Save and the name here will be update product Okay click on Save and last for the delete click on Save here and the request name will be delete product okay save again and great so we have all press save under the my API collection and we can organize this a little bit more by clicking on the options for my API collection and choose the add folder option and let's give a name for this folder so products and now we can select all request here and drag and drop inside the product folder great so under my API collection we have the products folder and we're going to create another folder for the categories as well so this new folder is called categories and we're going to save all categories requests inside this folder uh let me close all tabs here on the top okay so let's start testing our categories and points I'll open a new request here and let's start by creating categories so I'll change the method here to post and the URL I'll get the products URL saved in the history here and we'll change to categories and now we need to send a body so body Tab and I'll choose the raw option and select the Json type and here on the body I'll type an object and we're going to need the name field for the categories so I'll name this first one here the electronics and click on send okay we got 2011 and the details of the new category okay perfect so the name field is required so let's remove it from the body and click on send and great the validation is working giving the correct response let me put the name back and let's save this request and we'll choose the categories folder and the name of the request is create category okay let's save and let's create another category so body and the name of this one will be books click on send and great books categories created uh let me copy this categories URL here and let's open a new request tab to get all categories so I'll paste right here it's a get request and we can click directly on send perfect so here are the two categories we created on the response array great so we can save and it's already select the categories folder and let's name this one get all categories okay let's save perfect uh let me close these tabs here on the top and we'll open a new request tab to test the update endpoint so I'll change the method here to put and for the URL I'll select the categories from the history here and we'll need to to pass a category ID so let me open the get all categories request here click on send and let's update the books categories so I'll copy the ID here and on the put request tab let's type the body first so body tab raw and select Jason let's create an object here on the body with the name field and we'll change to courses now we need to paste the book ID here on the URL so slash and paste click on stand and great book was updated to courses let's check by calling the get all categories end point and perfect uh let's test some validation so back on the put request tab uh I'll change the ID here to one two three click on Sand and we got the response 422 parameter is not a valid ID now let me put the courses ID back on the parameter and I'll change the last character here to zero so this ID doesn't exist click on send and we got the category not found f message so the validations are working perfectly as well okay so let's save this update request and we'll name this one to update category okay let's save perfect now we need to test the delete endpoint so what I'll do here is select the update URL that already has the courses ID as a parameter copy and I'll open a new request here but before let's create a new category so I'll open the create category request and on the body I'll change the name here to books and click on send and the books category is created and let's just make sure by calling the get all categories endpoint and click on send and yes the books category is created so now we can delete the courses category so I'll open the new request tab from before and change the method here from get to delete and the URL will be the categories URL with the courses I ID as a parameter okay we can click on send and we got the 204 no content status code that means the courses category was deleted but let's check by calling the get all categories endpoint Okay click on send and yes now we only have electronics and books as categories so we can save the delete request to the collection and we'll name it as delete category awesome so we have all products and Cate ories tested and save on Postman collection let me close these tabs here on the top okay now we need to create new products passing the categories we have on our database but for that we need to change the post route in our project so I'll open the products controller here and inside the create product function under the category validation since it's still a required field on the schema so we can leave the if statement checking if the category is on the request body and now we need to change this else if statement here cuz we need to check if the category exists on the database and not on the N none anymore so what I'll do here is remove this entire statement and now we need to check if the category on the request body exists on the categories collection on the database for that we need to import the category schema on the top so right below the product scheme import I'll type cost category with a Capital C equals to to required and inside do do slash and the models folder slash category okay now back on the create product function on the else if statement we can add an exclamation a wait and the category schema and here we can use the exists or defined by ID function to check if the categories available in the database let's use defined by ID because we have the category ID on the request body so inside request. body body. category okay so if we can't find the category then we'll send the correct response to the client so we can remove this error message here and now will become category not found great now the post create product route is expecting a category ID on the body so let's test on Postman and let's open the create product request and on the body tab inside the object uh let's change a few things here so the name of will'll put node.js book and on the description I'll just put description here and for the price this one is uh$ 2999 we'll leave the quantity as 10 and now for the category we need to pass a category here so let's open the get all categories request and we'll click on send and let's copy the books category here now back on the create product request we'll paste the category ID on the category field and we can click on send and here it is the new product now has the category saved from the categories collection let's open the get all products request to check and click on send and perfect here's the category ID inside the product object but as you can see here it's returning only the ID of the category and the client might not know uh which category is this by the ID so we can send the category on the response as an object containing more details like the name as well so let's do that inside the products controller file on the get all products function uh right after this select method on Define method uh has an option here called populate which L us reference documents from other collection and as a parameter it expects the field we want to return the entire object details so inside let's put the category fi and that's it simple as that we can go back to postman so here on the response we have the category ID only but if we click on send awesome now we have the category field as an object containing all details so the client knows which category is related to the product and we can actually select the fields that we want to show here so back on the ghetto products function inside the populate method uh we can replace the category to an object and to inform the field we can use the path key and expect the name of the field so category and to select the fields we can add the select key here which we are already familiar with it so here we can put the ID and the name field for example okay so let's see how it looks on Postman I'll just click on send and perfect now the category object has only the ID and the name field let me copy the product ID here and let's open the get product by ID request paste here as a parameter click on send and here we need need to change as well because the category is only showing the ID so let's change on the get product by ID function and actually we can copy the populate method from the getto products function and paste after the select method here on the get product by ID function now back on Postman I'll just click on send here and perfect now the category is an object containing the ID and the name just like the get all product endpoint now let's create another category here so I'll open the create category request and we already have the electronics category on the database so if we try to create this again so let me click on send and it is created but now we have duplicate data on the database so if we check here on the get all categories request there it is we have two Electronics categories created so let's add a validation to avoid this and back on the code uh we can open the categories contr controller and inside the create category function we can add a if statement checking if the category name already exist on the database so before we call the create function and after validating if the name is on the request body let's add a n statement here checking on the category collection so await and the category schema Dot and we're going to use a method called find one uh which is going to return the first document object from a filter so inside the method we can add an object and we're going to filter by name so name equals to the request. body. name perfect so if we find a category with the same name from the name on the request body let's return response to the client so return response do status and here we're going to use the 409 status which means a conflict okay every time we we try to add something that already exists we can return this code and we're also going to send a Json response uh with an error inside the object and back ticks and inside the category and I'm going to put a dollar sign and curly brackets and request. body. name already exists great now let's test on Postman and open the create category request tab and let's try to create the electronics category again so click on send and perfect we got the 409 conflict status code and the error message saying the category Electronics already exists so validation is working and let's try to create a new category so accessories for example click on send and great the accessories uh category is created awesome so mongodb is not a relational database uh we can use of course relations but we have to handle all the details on the back end so for example here on the nodejs book product we are using the books category but what happens if we try to delete the books category so let's open the delete category request here and paste the book category ID on the URL parameter click on send and we got 2 104 no content status quo that means the category was deleted and if we open the G all products request Tab and click on send as you can see the category for the node.js book is null and that's an issue because on the product schema uh we Define the category as required through so before deleting a category we need to check if there are products using that category so let's open the categories controller and inside the delete category by ID function we need to check on the products collection how many products are used using the category we're trying to delete so first thing we need to do is import the product schema right below the category so con product equals to required and inside we're going to put the dot dot slash models folder slash product okay now back on the delete category by ID function so we're checking if the category ID send on the request parameter exists so here inside the lse statement before we call the delete one function we'll create a cost that will store how many products are using the category we're trying to delete so cost and we'll call this product count which is equals to A8 and we'll bring the product schema here and we're going to use a method called count documents and it's used to count the number of documents that match the filter we defined so for the parameter uh we'll add an object and we're going to filter for the category field and and the category ID we can get it from the category cost we have here or from the request parameter ID so and here I'll just put the category cost doore ID field so here uh we'll have the number of products using the category we're trying to delete now all we have to do is check if the products count is greater than zero so if products count greater than zero and then uh we're going to return response Dot and the status code here uh we'll also use the 409 conflict as well because we are trying to delete something that's being used for some other resource and a Json response here uh with the object inside and the eror message uh I'll add back ticks here so we're going to put something like category and and I'm going to put a dollar sign and curly brackets and we're going to get the category from the constant. name is being used in dollar sign curly brackets and inside we'll put the products count constant here and in here we'll put product uh like this so theer message is going to be something like the category name uh is being used in 10 products maybe and it won't proceeded with the delete okay so let's check on Postman and let's create a new product by opening the create product tab here and we'll name this one uh adapter and we'll leave the rest as it is and for the category uh let's get the accessories category ID recreated so on the get all categories tab U let's copy the accessories ID here okay and now back on the create product uh we'll just paste here on the category click on send and okay the new uh adapter product is created now let's try to delete uh this category so I'll copy the ID here and I'll paste on the parameter and click on send okay now we got the 409 conflict and the message saying category accessories is being used in one product okay so our validation is working and let's try to delete another categor so on the get all categories tab let me copy one of the electronics ID we have here here and on the delete category tab let's space here on the parameter click on send and perfect we got the 204 no content and let's just check here on the get all categories tab click on send and yes the category was deleted now when we try to delete a category that was being used in the products collection on the eror message uh we just received the number of products that were using that category but we don't know which products are those so the client might need an endpoint to get all products by a specific category so let's create that new endpoint and we'll create the function inside the products controller so right below the get products by ID function uh let's create a new one so export and we'll name this one get products by category and just like the other functions we created it's going to be equals to sync and the request and response parameters and the arrow function and inside the try and catch with the eror object block we are very familiar with this already let's copy the eror uh message we have here and copy on the catch okay now inside the try block we're going to create a cost that will store all products from a certain category and that category ID the client will send on the request parameter so let's open the products route file file and let's create a new route for this function below the get product by ID uh we'll put the router doget and the name will be slash products and now we're going to put slash category and we need the category ID on the parameter so slash column category ID note that now it's a category ID and not a product ID okay so back here on the route let's put a comma here and call the products controller get products by category okay so the route is defined back on the products controller inside the get products by category function so the first thing we need to do is check if the category the client is sending exists on the database so let's add an if statement here exclamation sign await and the category schema Dot and here we're going to use the find by ID and inside we're going to get the ID from the request. prams do category ID okay so if that category doesn't exist uh we need to send back the response for the client okay so return response and the status code here will be 404 not found and the Json message with the error so let's put here eror and the message will be category not found great so if the category was found we need to get all products that are used in that category so cost product and it's equals to a weight and the product schema do find and we already use the find method but without a filter so let's add a filter here by the category field and it's going to be equals to the request. prams do category ID perfect now what we can do is copy the select and populate methods that we already defined here here on the get product by ID route and paste in this new get products by category route so let's copy till the select here and let's paste right after the find here great so we are removing the version key field and populating the ID and name for the category field and let's copy the response as well and paste right below this product's cost okay and inside the Json here we need to change it to products and not product just like the const over here okay now let's test on Postman this new route and before we test let's create a new product with the same category from the adapter product which is the accessories category okay so this new product will be the keyboard and I'll leave the description as it is and the price will be 79.99 the quantity 10 and the same category okay all good with the data here so we can click on send and great uh product created let's let's check on the ghetto products tab click on send perfect now we have the adapter and the keyboard products with the same category okay and the no jazz book is actually new here uh Let's ignore it for now and let's use these two other products so I'll open a new request tab here and this one is also a get and I'll select the product URL here and add a slash category and let's get the accessories category ID let's copy and back on the new route let's put a slash here and paste the ID click on send and great we got all products that are using the accessories category ID which is the keyboard and adapter uh with all the information that the client needs let's create another product using a different category and let's use the electronics category now so on the request body let's change the name to laptop and the price to 300 the quantity will leave just one and the category will past the electronic category ID Okay click on send and the laptop is created now let's open the get products by category ID and point ping the electronics category ID here click on send and great we receive only one product which is the laptop and let's save this new request on the product folder and the name is going to be get product by category okay let's save and perfect and uh let's clean all this tabs here on the top so I'll just close all of them here so we can have a clean environment okay delete and the get product okay perfect so we created collections for all routes on our project and back on vs code uh let me open the Explorer here and let me close all tabs on the top okay perfect and as you can see here the structure of our rest API project is very organized we separate the the model files the route files and the logic on the controller files and on our main index file uh we're using only to configure Express the database connection and configure the route so everything is very clean one last thing we can change is on the categories route file uh all routes starts with a slash categories and on the products route file same thing so in the index.js file we can configure the path of these routes so right here on the app use uh before the required uh we can add these lash products over here and then we add a comma and then the required products route and for the categories we can do the same so in here will be slash categories and comma and the categories route file okay now inside the categories here all we need to do is to remove the categories here on the beginning of the routes okay and on the products route same thing so we just remove the products on the beginning okay uh let's just make sure these changes are working so on Postman I'll just open the get all products tab here and we'll click on send and okay uh we got the products now for the get all categories sand okay so everything is working perfectly so now if we need to change the path of the routes we only need to change in one place awesome so in this video we learn how to create an complete rest API using crud operations with node Express and mongodb using the module we learned quite a few helpful methods and functions from we learn how to organize the endpoints on Postman and we also learn how to create a cluster on mongodb Atlas I'll leave the project GitHub repo link on the description below thank you so much for watching and please subscribe on the channel so we can make more videos like this see you on the next video
Info
Channel: manfra․io
Views: 1,526
Rating: undefined out of 5
Keywords: node, nodejs, node.js, rest, api, rest api, rest api with node, express, node and express, node and mongodb, node and mongo, mongodb, mongoose, database, coding, programming, it, vscode, npm, json, postman, endpoint, http, products, categories, routes, controller, mvc, javascript, backend, server, nodemon, crud, learn node, node tutorial, rest api tutorial, mongodb atlas, cluster, manfra, manfra.io, tutorial, github, repository
Id: zEfYL0GtcP0
Channel Id: undefined
Length: 119min 46sec (7186 seconds)
Published: Thu Jan 11 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.