Build Scalable REST APIs in Node.js with Express, Postgres & SequelizeORM (2-Hour Masterclass)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
whether you are a beginner or looking to enhance your skills this step-by-step guide will take you through the entire process of building robust and scalable apis in next 2 hour we are going to learn everything you need to create rest apis using node Express postgis and SQ orm so let's have a quick look what we are going to learn at the end of this video so we'll start from first the project setup then we will work on creating the express server then we'll do the postman setup to test the apis then we will work on Project folder structure to organize the code in different folder then we will set up the environment then we'll set up SQ orm to perform DV operations then we will generate our first model and migration file then we'll work on sign up process then we will work on password validation and encryption then we will work on J web token then we'll work on login process then we will work on Express Global error Handler to control all the errors messages from one place for different environment then we will do the code refactoring after that we will work on validation and constraint then authentication authorization Association Cedar and so many more things we are going to cover so watch this video till the very end I have already pushed this code into the GitHub repository and you can get this link from my description so at any point of time if you stuck you wanted to check my code you can come here and have a look and you could also install this project into your local environment it's very easy you just need to add this environment variable inside your projects I have already given sample. EnV so just rename this file Tov and fill all the missing information here and then you just need to run these three command so this will install all the packages and this command will do the migration this will create all the table into your databases and then this will feed the default data into the table so you could start using application and then you can enjoy my application so hi guys it's me Tarik akar Ansari so let's start this video so so the first thing you need to do is you need to install the nodejs you can install from this official websites I'll give all the links in the description so you can follow those links to download nodejs now the next thing I'm going to use Postman for testing the API so you can download the postman by searching on Google and follow this link to download and the final thing like I'll use VSS code editor for writing the express code so you can download install and you can follow me but it's up to you if you want to follow some other editors it's completely fine no problem so now let's start let's go to the folder where you want to create your project so I'm inside the D folder let's create a folder here let's name it Marcos I love this name so let's go inside this folder and open the command prompt CMD let's initialize the project here npm init minus y so the package.json file created let's open the vs code on the same folder code dot now you can make sure that we are inside the Marcos folder so let's open the terminal first and let's cut the welcome screen now here you could see we are inside the Marcos F so let's install the express first npm install Express so Express installed successfully now let's create a file here app.js now let's quickly import the Express package W Express now let's create the express app app equal to express perfect now let's create a route to check that it's working oops app.get slash and let's take two things request response it has one optional parameter next we'll discuss later on so let's take request and response and give a response from here response. it has status as well you can give explicitly the status 200 but if you don't specify by default your response will go on status 200 let's give response on G format status call it success and message AP are working perfect now let's run this application node app.js oops okay so we need to call Express function perfect let's clear this and now run it now we need to do one more thing app. listen so it will start listening on some ports so I'm giving here 3,000 and it receives a call back function so let's do console.log server up and running perfect now let's run it again now start listening on Port 3000 so let's quickly check we could check on browser as well if we hit Local Host 3,000 here we could see status is working but usually we don't uh hit the apis from the browser we have the post man tool that we will use so let's create a folder we call it here collections so let's create a blank collection here name it as Marcos let's add a test request here click on the folder add request name it test and make sure the method is get because we created the get route let's add HTTP Local Host 3,000 and hit now here we could see the response in J format success and message looking so our Express app start working now let's start creating the folder structure so the first folder I wanted to create here is control controller so this folder will be responsible for like all the controllers so we'll control the r Express app logic from here now let's create one more file folder actually route so this will be responsible for handling all the routes uh let's create the controller first so inside this create a new file Au controller. gist so all the Au related things I'll keep inside here like sign up login reset password or and other stuffs here so let's create a function here like sign up it will take three things request response and optional next function so just for now let's give a response from here like response. status success message sign up rout are working just giving to check now we need to export this module so that we could use module. exports and let's export inside the object sign up so that in future if you create login reset password and other so we could also like add inside this object and we could export it from here perfect now let's go to the route folder and create a file Au route. J so this file will be responsible for all the routes related to like sign up login reset and others so all the Au related routes so let's quickly create a router const Router equal to require Express router and it is a function perfect now let's define the route here router. route and the route will be SL sign up and this route we could would add different different methods like get post and other so let's define the post for now and we'll call this sign up controller this sign up from the controller if you remember from the Au we defined there right this sign up and we're sending the response from here fine now let's export module. export ports equal to router because we just need to export the router that's all from now now this file will take all the request from here and we transfer to the controller and contr controller will do the business logic but this file is not connected with app.js file so right now this is not going to work so we need to connect this from here so let's connect it so I'm giving a comment here all route routes will be here so let's quickly add app.use and I'm giving like API slv1 slash Au and let's add the auth router here so like let's import that first const o router equal to require route Au route perfect now let's pass this to here so now what will happen if we request to API SL it will transfer to this and then it will match to the signup so and it will transfer to this controller and will give the responses from here perfect now let's go to the postman and create one more route oops click on three dots add request name it sign up let's quickly add this sign up HTTP colon doubl s local API slv1 sl/ sign up and this will be the post method perfect just hit for now and check are we getting the responses so we getting some error cannot find IPI slv1 SL SL signup so let's quickly see that why oh so this is because we need to restart the application so every time we do the changes our application is not going to restart automatically so how we could fix this issue so so we have one package which is called node modon so let's install npm install hyphen save H Dev node Point perfect now let's install this so not one installed successfully let's check so it is installed as a Dev dependency let's add one scripts here like start colon def if we write this command then noemon app.js perfect let's clear and run the command npm Run start colon Dev perfect server up and running now let's go to the postman and hit this now here you could see sign up routes are working so our structure started working and it is started taking in shape now let's do one more thing uh so we usually we don't pass this uh named uh like the value directly here we keep all these values inside the file so we keep all the sensitive informations like uh username password these things inside the EnV and we use the environment variables here so let's quickly add file so for that we need to add one more package so let's do that npm install. EnV now EnV packages get installed now let's create EnV file do EnV perfect now we can uh add here like appcore Port equal to 3,000 and we'll use this variable inside here like using process. env. app. now this will not work we need to make sure that our app.js file knows about this our application knows about this file so let's quickly add in the first line as require do EnV let's config it it will take path and let's give a proper path here so we'll use process. current working directory so it will return the current working directory which is D drive maros but if this application run on server it will give their current working directory perfect now let's slash and add. EnV I see few people use like very shortcuts they don't don't do this they directly like do the config by default it takes it but this is the best way to do it okay now they know about this so let's quickly store inside a variable const Port like this and if we don't found this port then run on 3,000 like this for now just make it 4,000 so we'll understand if we don't found this value here let's see save this let's run this application and Pim Run start there okay and now here also add comma Port perfect so we are running on 3,000 so now our application knows about file and it started working fine now let's see one example if we try to call some route which is not available in our applications what will happen now we started getting the HTML response we don't want this we want the response should come in gon format even if that route is not found so let's quickly fix this issue let's go back here and after all the routes you need to use app.use and specify do asri so it means if no route match this is going to match and it will take request comma response comma next next is a middleware in Express so we'll come on it later on so we'll give the response from here response. status let's make it 404 not found and we'll give injection response as status col fail okay message route not found now let's check now if I call this so we started getting the response in perfect shape even if that route is not found if route is found and here you could notice like we also started getting the status not found but if we call the route which is available we get the status 200 and we're getting the responses in G format now let's work on database Integrations and we are going to per perform all the database related operations from sqy orm so let's install the sqy orm so this is the official website of sqy orm I'm going to give the link in the description you can follow for more informations now click on getting started and now first install the SQL eyes let's run on Parallel one more CMD now this is installed let's install other things so I'm using postgis database so I need to install the postgis driver if you're using any other database like MySQL So based on that you can install your driver and you can follow my video after that all the things will be the same only the driver will be the different here now let's install this as well perfect one more thing go to the migration section of SQ eyes and I will highly recommend you to read all these things from this section very carefully because this is one of the sections we use everyone use a lot when you're building a production grid application so let's install the sqy CLI first perfect so in the migration section if you go down you'll find a file dot sqy RC and copy this information from here and create a file inside the root label dot sqe RC and paste here so this will tell the SQ CLI to create all this folder inside the DB folder and this database doj config file inside the config folder but I don't want the database dojon file I'll use config.js because in Jon file you cannot use environment variables and we wanted to get all the credential from the environment variable so this is bound to me to use config J and I will recommend you to use the same as well now let's run the command let's delete the second one let's stop here let's run the command npx SQ CI init now if you notice all the files gets created inside the DB if you see we have three folder migrations model ceders and inside the config we have config doj so this object is a gan object for now if we write here uh let's convert into the JavaScript object so just write module. exports equal to and save it now this is converted into the JavaScript object so they will pick the credential information based on the environment so if you are running on node en on development mode this will pick this object if you're running on test it will pick this and in the same way it will pick from the production so we just need to change the environment variable no D EnV and based on that automatically it will pick the credentials now as I said we are not going to use these informations directly so we'll use using process. EnV DB username in the same way let's use for others like for password I'll use DB password let's copy and do the same for database base name I don't want to do any hardcoded value here even for the host just paste here and one more thing we'll use the port number if you're using the default Port like uh the postgress default Port is 5432 then you don't need to specify but if your port number is other than the default then definitely you need to specify those as well here now let's change this quickly perfect now this file don't know about the EnV because this file is going to run by the CLI so we need to specify like we need to configure in the same way like we did in the app.js file so just copy the same thing and paste here now they will know about these all the environment variables now go to inside the environment variable and Define all this username password and everything here I already did that username password database name host Port you can get this like username and password when we when you install your database I haven't created this database Marcos DB yet so if the DB is not present so let's run the command if this user the post Grace has the access to create DB then it will create that if it has all the Privileges but usually you will get the database name as well so you don't need to write this query in the Productions you mostly get username password and database name these three things you get at least uh okay so one more thing we need to change here is dialect convert into the post so just tell that SQ CLI we are going to use postgress not MySQL now let's try to run it again see that it's pick using environment variable development and created the maros DB so I was talking about this.b file if you change this to production it will pick the production object from this config file now now we did the Integrations now let's create complete the signup process so for that we need sign up model so let's create a model here so the command is same npx sqe CLI model colum generate now specify all the fields here first name String comma and one more thing user type let's add user type it will be a enum we will have three users in our application which is admin seller and buyer so let's create this quickly so it will generate two files one is migration and another is model file we made some mistakes here so we need to do two things here squize model generate hyen hyphen name we need to give a name so we are going to give it name user and also hyen hyen attributes see here you can see these informations here right so we were missing these two parameters so we pass this now let's hit enter hope this time it will create perfect here you could see there is two file created one is the model and second is the migration file now inside the migration you can see they have already generated the ID primary key Auto increment and user type enam let's add three things zero for the admin one for the seller and two for the buyer so there will be the three times of user first name last name email password and they have added two things created at updated at and let's add one more thing so we do the basic thing from the CLI if you miss any any field we could also add here deleted at because we wanted to use soft delete so we need it let's define the type as well and don't make it allow false here because this could be null values initially this looks fine now so let's do the same modification inside the model file so personally I don't like this class way to define the model but if you like it you can go for it there is no problems but caliz provide one more way of defining the model which is sq. Define method I'll use that one but for that we need to create this equalized object so let's do this first database connections we have haven't defined that yet so let's create one more file name it database. JS so we'll do the connection here so let's quickly import sqy class from sqy package we can create this sqy object sqy and we need to pass the configuration here config so from where we'll pick the config obviously from this file and based on the environment we wanted to pick this and we'll pass inside here so let's do that quickly const config require. SL config and based on the environment so let's quickly create const EnV process. env. node EnV and if you get it fine otherwise by default we wanted to make it de development perfect now let's pass this here and pass it config here so it will pick the config object now if this is confusing you just remove it from here and add it here both are same now we need to export this from here module. exports SQ fine now we can import this inside this from the database fine so we imported from here let's add little bit of space here dot Define it has a method Define and let's give the name and it will have the same objects which is what we have here so let's copy the same object from the migration and go back to the model paste it here now they don't know about this equalize we can import this equalize and it will work perfect so all the data types gets imported now let's add extra informations here by default SQ to the plural now if you remember that here if you see they make it users I have created user but they make it users I don't want to change the name I want to keep the same like what we Define so keep it user so we need to to pass the same informations otherwise they will also make it plural to use inside the application so there is freeze table name we pass true it will be the same it will freeze the name now let's pass the model name which is user one more informations I wanted to use here paranoid let's make it true if you specify this it is going to enable this soft delete feature so your actual data will not be deleted from the table it will just marked as deleted to make this work you need to specify deleted as column inside the table so then only this paranoid feature will work so make sure that deleted ad is present inside your migration file as well as in the model then only this feature will work now let's try to run the migration and see uh the table gets created on database or not let's quickly run the migration so the command is same sqe DB column migrate so what this command does it will pick all the migration file here those have not been run previously so this is the first time this file is going to run so this will pick this file and it will create the actual table inside the database now if you go to the database just for now I'm going to show you here let's quickly refresh see we have maros DB inside that if we go inside the schema table we don't have any tables for now now if we run the db. migrate and let's see hopefully it will run successfully perfect so migration gets run successfully now let's quickly see just refresh it there is two table you could see so see equalize meta so this is the table keep track of what are the migration migration files already run like if I open this table now here you could see the name of the file that is run so by default equalize keep track of all the migration file what are the migration file already gets executed so the next time this file is not going to execute now let me tell you a very important things here in future when you have a lot of migration files and you think you need to modify the user table then few people may think like they will come back to this file and do the modification and rerun the migration that will work this is not going to work because as I already mentioned SQ I keep track of migrations so this file is never going to execute again so your modification is not going to be reflected inside the table so the way we do the modification is create a new migration file and do the alteration in that file and that will do the real changes in your table having said that SQ also provide the migration undo command that will just do the opposite of migration so it will revert the recently migrated files so the command is npx equal CLI DB migrate undo so this will delete the recently like in my case it will delete the users table and delete the history so we could rerun again the migration but this command is fine in the development so in my case I could see the user table Nots get delet deleted there must be some issue so let me fix that okay so I found the mistake here like when we create the migration file if you remember there is two method up and down up is run when you do the migrate to create the table and on the down time I run the drop table users it should be user the name should be the same here in up as well as in down so that's why our database are in inconsistent state so let's do the run the migrate again and this time if I'll do the undo it will work it will delete the user table see this is migrated now if I do the undo it will delete the table perfect it is now let's this time hopefully it will work perfect now here you could see the table gets deleted once you do the undo then you can do any editing into this file because this is going to rerun again but but why I was telling you not to do any editing here because once you migrated this file into the production database you may have the sensitive information inside this table and doing undo you may lose all the data from the database maget and undo has one more options like all if you wanted to migrate everything like undo everything then provide these options as well now let's run the migrate only perfect so table gets created let's go inside the controller so now let's remove this and start working on sign up process so we'll get the data from the user in a format so body will get the data in request object inside the body they'll provide now we cannot get so how we'll get the G response so the one thing we are missing here in app.js you need to use app do use and pass express. gation function so this will do the conversion of data which is coming from the request object into the J format otherwise you're not going to get the data here so let's come back to the Au controller so now we'll be able to get it now let's first check the user who could do the sign up only two types of user Sor and buyer admin cannot do the sign up includes and let's check body do user typee so if that is not one or two then we are going to send them the response the error response so we'll return response response. status with 400 battery request dojon status colon fail message invalid user type and if this is not the case now we can insert the data inside the user table let's new user equal to let's use the user model from Models remember that the path so we import this from the models user and we'll use this one do create and let's pass all the information here so what are the informations we have user type will be use body do user type first name column body do first name last name body do last name email body. email password body. password now this is ready let's check the condition so now let's check the negative condition first and give the error response to the user so now let's copy the error response from here and paste it here failed to create the user now if this is not the case then we'll respon success then we'll return response. status 2011 that is for created and in Su status success and we'll return the data new user now let's check this is it working let's run our application now in the sign up we need to pass the data in the body draw injection format user type will be let's take it as one password will be test 1 2 3 now let's hit this and see here we could see created and we are getting blank object so there is something issue but at least this is working so let's check that does the data came into this table yes data is coming here but we didn't get the response so this is the asynchronous code actually uh it takes sometimes to create the database and this is asynchronous code so we we need to wait here and if you're waiting here you need to make this function as a sync right now this will wait to get the response back and then it will give you the answer so let's run it now perfect now you can see the ID to because I call this API two times and all the information is here and here you could see password is also stored in plain text so now let's work on password encryption at the time of sign up we also take confirm password from the user but we only Store password inside the database so let's take confirm password body dot confirm password from the user now let's go to the model user model and inside that let's create a confirm password let's give comma here and the type will be virtual so squal lie dot virtual so when we create any column with a virtual so this will be used inside the program only this is not going to be stored inside the database if you have noticed we don't get any auto suggestion like here we don't get no suggestion is here because we using SQ class in inste of that if you use data types let me show you data types this class from the equalized package this will give you the auto suggestions like let's check here if we type data types dot virtual here you could see it so now let's update all the sqy class and convert into the data types both are same it's not a problem but I prefer to use data types instead of SQL eyes because it's G keep Auto suggestions fine I have updated all now SQ also provide a getter and Setter method so let's use here set value if value equal to this do password means both are same and if both are not same let's give the throw the error throw new error password and confirm password must be the same now if both are same now let's do the hassing const hash password equal to here we are going to use a package the name is bcrypt that will help us to encrypt the password so this is the official site of that package and here you could see the weekly download of this package so this is a very popular package so let's use this package for password encryption and let's install inside my project so the package installed successfully now let's import this package right here const B grip B grip let's use this bcrypt Dot and it has a method hashing so it will receive two things data that we wanted to encrypt so let's pass value here and the second is sh Sal so here I'm giving 10 so 10 round of salt we will use to generate the encrypted password now if you get it now let's this dot set default use set default value to set and pass the key I wanted to set inside the password and this hash password so before inserting into the database the password value will be updated to the hash password and then it will be stored inside the database now let's make sure we have here now let's go back to the postman and add confirm password and make it test 1 2 3 apply comma here perfect now let's send this request oops my server is not running let's start the server server started successfully now let's hit the request and this time you could see we are getting the encrypted password so even if password is encrypted we never send back to the user and also we send the token to the user so once user done this sign up successfully they don't need to do the login again to get the access to the application so let's work together to remove this from the response and also add the token inside this response so let's first delete so the first thing I'm going to hear to convert into the JavaScript object so let's take result equal to new user. toj so this will convert into the JavaScript object instead of model object don't be confused this is not going to return the Jon string so this will be the JavaScript object now we could apply delete result. password let's also delete result. deleted at from the response and now we wanted to add iser do token so the Gan web token we wanted to send back to the user so we need to use the JWT package so let's install the Jon web token package here npm install j web token so token installed successfully let's create a separate function generate token it will take the payload so let's pass the payload ID colum result. ID so inside the payload I only want to keep the ID we could keep more informations but let's keep ID only and I'll get this ID when user will uh send the token and based on this ID I could get the user information from the database so yeah so let's define this method on top const token and it will receive payload and we need to import const JWT from J web token now it has a method DOT sign and it receives payload the second thing secret key I will highly recommend you to use a long and complex secret key here don't use a simple word like secret or something here so like very long but don't use the same so it's just for the example and the second object we use here which is expir in J web token we keep very long expiration time so let's use 90 days here days but we don't keep these informations inside the code let's use this using the environment variables so let's cut this information from here go to environment variable and let me do a comment here GWT info JWT red key remove the single code JWT expire in let's give 90 days now let's use this key here instead of Direct Value so dot this save this let's copy this and also save this file come back here process. EnV do paste this so it will generate the G web token now let's return from here and let's use this function here just to generate the token perfect so this will generate the token and it will add inside the result and let's check the result instead of new user and also here update this now save this file and make sure you have saved EnV as well now let's run the project now let's go to the postman and hit again now this time you see password is removed from the response object and we also added the token but deleted at still I could see there so let's quickly have a look here did we miss that deleted okay deleted ad it's just an spelling mistake so let's send it again perfect so deleted and also removed and we have this Jan web token so they could use this to get the access now you may guys have noticed like I'm using the same emails so usually we don't use the same email to sign up more than one account we will work on the validations later on so now we already know how to generate the tokens so let's quickly create the login functionality let's define one more controller login so we'll receive email and password from request body now let's check so if either email or password is not present then we will give the response pass please provide email and password so now if this is not the case it means we get the email and password from the request body now let's fetch the user from the database find one apply where condition email colon and we'll pass email so instead of writing email email just write email this is same now let's check we get the result if it not it means email is incorrect let's give status 401 fail email or password now if this is not the case it means we get the user now let's compare the password and match const is we need to use bcrypt package here so let's import the bcrypt first now let's apply bp. compare it takes two things the password which we received from the request body and the second encrypted password that we get inside the result object from the database so let's compare both if this is compared successfully it will return true otherwise it will it will return false this Returns the promise so we need to apply a weight here and if we use a weit then we need to make this function as sync perfect now if password match is incorrect if we receive false then let's apply the condition and we need to response the same because we cannot tell the user like incorrect email here and incorrect password if we do that we are going to give information to hacker that okay they know that the only email is correct at this point of time and here they know that only the password is incorrect so usually we keep incorrect email or password instead of giving one by one message okay so now instead of writing the same thing in two times let's apply the same logic in one place here let's put not condition and let's delete it perfect now let's generate the token we need to pass the payload and inside the payload we'll only pass the ID from the result object do ID now we get the token because we already generated this we already have written this function right so now let's return the actual success response response start status token perfect okay we haven't written return here otherwise if you don't write the return this part will get executed okay and you'll get some error and also we need to return from here so this code don't execute once this is true perfect now let's export this controller from here and go to the out route and Define one more route router. route login dot this will also be a post method and let's use login here it's automatically imported now let's check that is it correct or not let's duplicate this let's rename it log now let's change this path to login and inside the body we will only pass email and password and let's remove all the other information now if you remember guys we uh have added a lot of user with this same email so this could be a problem and so let's first clear the database and create create only one record inside the database so we know that how we could do this so just run the migrate undo it will delete the user table as well as it will remove all the records now let's rerun the migrate so it will create the user table inside the database perfect now let's do sign up one once okay we need to run the application as well now let's run the sign up ID you could see here one and this email is registered with the password test 1 123 now let's go to the login perfect now let's hit the send request we get error let's fix it so the reason is we forget to add a weight here because it takes sometimes to find the user so we get it and then we pass it so now let's check it and don't be worry we next we are going to learn about the validations and error handling now here you could see success and we're getting the token now let's check what happens if we don't pass any one of the fields please provide email or password now if we provide incorrect password incorrect email or password now let's suppose we provide incorrect email still we receive incorrect email or password now if we provide everything correct we get the token now let's work on error and validation so this is one of the very very important topic as a backend developer if you miss any error or validation inside your applications you may crash your server or can let the hackers to gain access on your server so I will highly recommend you to watch this section at least two time if you have a difficulties to understand anything in this top topic but still I will try my level best to make this topic very easy for you to understand so let's start let's go to the app.js express provide a global error Handler to handles all the errors that occurs in our application so let's define the global error Handler of express it receives four parameter error request response next so just for an example let's throw the error from here this is error so we'll be able to cast this error in our Global error Handler so let's give a response from here let's change this to error and let's give message as error Dot message so this error will represent the error object so every error has a message property and now let's check it so if you try to access any route which is not present so this middleware will throw the error so see this this is error so it means we are able to catch the error now there is one issue here like if any middleware becomes a sync now global error Handler will not be able to catch those error let's check now now see this error crashed the server so how we could handle this error still we have a way to handle this error we could explicitly call the next method with error arguments so let's call this error with this argument in this way we'll again we'll be able to handle the error let's check it see this we are able to handle the error so the simple means Global error Handler will not be able to handle the async error but yes we could handle those using the next function and we could pass the argument inside the next so next has a two features in Express you can call the next without arguments to call the next middleware but if you pass any objects error objects here it will directly call the global error Handler so that's why our request came to ha now sometimes error could be thrown from the third party packages so in that case we'll not be able to call the next function so let's take an example in O controller inside the login if you see that this middleware is also the async middleware now if we if the error is thrown from the SQL I then our Global error Handler will not be able to catch those errors so in that case we left with two options one is try catch so in inside the every middleware we need to use try catch to handle this situation and inside the catch we need to call the next with the error but I have a better way to handle the async error so let's create a folder utils let's create a file catch async.js let's create a function con catch as so this function will receive a function because it is a rapper function and we will return a function from here error Handler it has a three parameter request response next now inside this function we'll call this function with this argument next and this function will be Asing function so we could handle Asing functions using do then do catch so let's use catch we need to pass a call back inside do catch and then we could call next with the error which we received inside this error but instead of writing this we could write in short hand. catch instead of passing the call back let's pass the reference of next function inside the catch this will work in the same way now let's return the error Handler perfect now let's wrap all the middleware with catch Asing function so before that we need to export this module. exports catch sing from here now let's apply first on app.js so let's apply on this sing function let's import this now let's wrap this Middle where catch using now previously when we throw the error it wasn't working now let's again instead of return and call next let's throw the error again let's see if this time Global error Handler will be able to catch or not see so this time we'll be able to handle this error let's just for sure add anything here and see yes so this is so if you wrap all the middle Wares with this catch asnc if any error thrown from you or from the global error or from any packages still we'll be able to catch those error and we could pass those error to the global error Handler we cannot give error messages directly to the client but if if the error is generated by us in the application then we could trust the error message but but sometimes error could also be generated from the packages so we cannot give directly error message to the client this could have the security risk so now let's differentiate from the error that we generate inside the application and the error that is generated from the packages or from the databases so let's create a custom error class name it app error. JS let's create a class app error extends error class let's create a Constructor my error will receive two things message and status code we'll pass the message to the parent class using the super now let's use the status code to initialize status code code now let's take one more property status So based on the status code if it starts with four then we'll give fail as a status otherwise we'll give status as error now let's add one more property to this error is operational true so this property will tell us that this error is a custom error that is generated by us and if this property is missing inside the error then probably we cannot trust to those errors now let's also add stack Trace error dot capture trace and then pass this comma this. trctor so this is a syntax to capture the St R so you'll get the line number and file name from the where error is generated now this custom error class is ready let's export this now let's start using this so let's go back to the app.js instead of throwing this error let's throw our custom app error and it receives two things so we could also pass the status code here perfect now we could send the error now this error has status code so error dot stateus code and now let's D structure this to send this state stus error dot status message error Dot message and stack dot stack now let's see so if we try to access the route now this time we see the status fail 404 this is the error and we also get the line number and file name as well at the time of development St race is very good to identify the errors and their origin but in production we cannot send this stct Trace so let's separate the errors for development and production and as well as let's use the E operational property so we haven't used is operational to identify that the trusted error or not so before that let's do the refactoring let's create a separate error controller that will be the responsible for sending all the errors doj and instead of directly writing here let's create a error controller const Global error Handler it receives four parameter error request response next now let's export this module. exports Global error Handler now let's pass this here and let's cut this perfect let's import this and go to here and Define this error now we want to send the different message inside the development and production so let's quickly create two methods and first check if process. EnV do node EnV if it's development we'll call send error Dev function and we'll pass here two things error and response and they'll give the response from there return from here here and then let's call the send error prod this will also receive two things error and response perfect now let's define these two quickly if we are in dev then we don't need to worry a lot let's receive error comma response here let's make it as Arrow function con status code we'll try to get it from er error do status code if not if that is not present then we'll give 500 const status s error do status if not present then we'll give error message error Dot message and we could also give stack T cons stack error do stack fine now let's quickly generate the response response. status status code doj let's status colum so it will be the status then message and finally we'll give stack as well we don't need to check is operational or anything because even if if you leak the uh sensitive information it doesn't matter because this error is going on dev environment now let's quickly Define the same way if it's production error then we'll get all the informations and then we will check if error dot is is operational if that is the case then fine we can return from here but still will not give the stack TR inside the production fine but if this is not the case then probably we'll return with response. status 500 and J message status let's give error message will be something went very wrong so it means that error is not handled by us anywhere inside the application so let's remove this from here let's remove this as well now we sap segregated the errors if any error that we get it from like this equalized package or anything we could convert those error into our error so that we could handle it uh so every error either will have the code or will have the name so we will do like let error blank initially but if you find if error dot like code there is something 51 something like that I'm just giving an example here then we will convert those error into our error so we'll do like error equal to new app error and it it will be converted into R errors and then we will pass this error inside this inav and production based on the inv enironment we will come to this place to handle the errors which is not generated by us let's check that uh does it working or not so please save this app.js file as well as error controller this file and now let's check still it's working fine now if we change the environment let's quickly change the environment but before that we need to update this uh config.js as well if you change this to production then it will pick this information and this is not the correct information information so let's quickly just copy this for now but we are 100% sure in production this information will be different this is not going to be same now let's go to the EnV instead of development let's make it production fine now save this now again this save any of the file just to reload the server we s this now if we try to run this again this time we are not going to get this St Ras so we not going to leak any information to the client now if in production application we get this error it means that error is unhandled that's why we reach to this point so the best way is to just do the log before it so that if anyone complains about that they are getting something went wrong error so you can look into your logs to identify that from where this error is originated what is the message and this tag so you can keep this inside your logger so that you could quickly fix those error now let's let's refactor the code so let's start from the app.js so the first thing let's remove this we added this initially just to check that server is running or not let's remove the space from here and let's update this route is not found or we could give better message like this can't find the requested URL on This Server so it will give more information now let's go to the O controller and rrap our sign up with catches sync catch sync rapper function now instead of giving direct response from here let's throw the error app error and here we'll pass this message invalid user type and 4 400 as bad request now let's delete it now in this case I made a mistake here like if you add the token and if you check this condition we'll never reach to this point so let's update those to here or let's do it even before this but check new user so here also instead of giving direct response from here let's throw throw throw or call the next if we calling the next so we could return and call like next and generate new app error both will work 400 perfect now if everything is fine we'll give them the success response so this is done let's apply on login as well and let's preactor it as well the same way here let's return and call next 400 now we don't need this one so let's do here same thing perfect now this is also gets updated now let's quickly check everything is working or not let's start from the sign up let's call this sign up route it's working fine if this is not matching something went very wrong we get this error okay now let's go to the console because we did the we haven't saved this actually so let's save this again and let's call again now here we could see this error password and confirm must be the same and this error we occur from the user.js line 3827 so see this how we could fix it go to the line 37 error instead of throwing this error let's throw app error and type like 400 bad request now let's see are we able to get perfect password and confirm password must be same do login working can't find the here you could see this is the message can't find the app login this on the server perfect now let's remove this and do the login yes yes here we are getting this now let's work on validation and constraints so the first of all let's understand the difference between validation and concern so validations are checks performed in sqz level in pure JavaScript so if validation fails no SQL query will be sent to the database at all perfect on the other hand conerns are the rule defined at SQL level the most basic example of the Conant is unique constant so what it means if you wanted to Define any constants like uh take an example in our case we are going to Define email as unique so we could only use one email for one account so in that case we need to update the migration file but if you're defining any validations you don't need to update the migrations you can directly Define inside the SQL model and that will be enough you don't need to touch the migration but uh let me also explain you the not allow null validation so this is the only validation that is mixed of both which is validation and constraint so if you allow in uh migration file this will update not null in SQL and if you miss that if you apply only on model then it will do the validation in javascripts only and it will not fire the queries let's apply in our projects validation and constraint so what I'm going to do I'm going to only apply unique key constraint on migration so as we know this migration is not going to run so let's do the undo first and then run the migration so this will update the unique now we done the undo migration so it means our table and data has been deleted so let's first create the record so we have created successfully if we try it again what will happen let's see so we something went very wrong it means the error is not handled yet let's see what we get inside the console because in error Handler if you remember guys if we get anything we do the console error name message and stack as well so let's see what's the error name is sqy unique constants we didn't handle it so let's handle it here so if error. name to this then we know that this error is thrown from the email so email uh must be unique so let's update the error equal to new app error and inside the error do errors zero you'll get the message so which is message this one and let's also give 400 status code perfect now let's try it again does it resolve yes it is resolved email must be unique so in this way we can handle the unhandled errors now let's apply validation inside the user model validate and inside this object let's apply starting from not null and let's give custom error message null user type cannot be null but this will not work now here you could see we get the error so not null will only work if we apply allow null false so as I said allow null is a mix of both uh validation and constant that's why we apply outside of this validate otherwise we all the validations we apply inside this validate so let's see like we apply not empty this will also take an object and let's give custom message here user type cannot be empty in the same way let's copy this from here and apply the same thing inside the and inside the email we'll apply one extra EAS email and let's give custom message invalid email ID now let's copy in the same way let apply inside the password password cannot be null now we wanted to apply one more thing so due to some reason I'm not sure why this Len property is not working so we also wanted to apply the validation inside the password so length must be greater than seven so still if this is not working I have another way to apply the same logic so I'm going to apply inside here so if the password length is less than seven we will throw this error and we will also give 400 as status but if you know and if you get the solutions please write it down inside the comment so others could also take the help from your comments okay now we did the validations I think now this time is to let's check the validation does it working or not so we set the first name as null just to check my validation is working or not so here we see something went very wrong so it means we haven't handled this error so let's see inside the console so we need to handle sqz validation error so let's apply here quickly so error name sqy validation error and if we get this error so let's convert those into our own custom error so that we'll be able to handle it now let's save it again let's send the request we have first name null then first name cannot be null let's make it first name empty C first name cannot be empty perfect if you find the add the name test now let's see what errors we get it it is created successfully with the ID now if we hit the same thing again email must be unique we started getting this if we reduce the length of the password password must be greater than the length 7 so all the validations are working fine so now let's generate the project model at this point of time we already know how to generate the model and migration file so here uh I'm going to execute SQL sqy model generate name of the model is project and attributes just I'm taking title uh and the rest of the missing attribute will add directly inside the migration file so let's quickly generate so it's generated two file model and migration so let's quickly update the migration file before running the migration so here we just have the title ID title created at updated at and let's add all the missing Fields here so here I have added all the missing Fields including the allow null constant so as as I already explained allow null is a constraint and constraints usually we apply on the database level so that's why I have applied here allow null inside the migration file so if you have any constraints you have to apply inside the migration then only it will be applied on database level so on title is featured so if this is true then this project will be listed inside the featured section product image this will be array of a string so you can upload more than one product images price the data type will be decimal allow n is false sort description so basically we have two kind of descriptions sort and long so sort we will use to show inside the list and long description we'll use when user will click inside the product and they could see the complete detailed description of the product product URL so basically I'm assuming that you will have a separate API to upload the product whether it is a PDF images or video and then you'll get the URL from there and you can upload here category this will also be array of a string tag array of a string created by so this is a foreign key so here I have applied the references model it will be user not capital u because my model name is user and the key is ID that we wanted to refer here so this is a reference key so this is the way you can Define the reference key created ad updated ad and deleted ad so if you wanted to use soft delete features paranoid true then you need to Define deleted ad then only it will work otherwise it will not and one more thing guys as previously also we faced by default sqi do the plural names they use the plural names so let's convert these names into the singular I don't want to update the name table name so this will be project this will down will also be the project fine now let's quickly run the migration and see npx equalize CLI DB migrate so this migrated successfully now if you have noticed this use the production you environment because last time we have upd no DMV to production so let's do the development and just for your knowledge if you remember that in production and development both are connected to the same data base so that's why we don't need to run the REM migrations it's fine so in the same way let's update the model so let's delete this way we'll use module. exports sqe object defined give the name project and here it is I have defined all the ID title and everything but this time I just use data types instead of SQ eyes just import this so this will be imported from the SQ I package data types and I have just applied the validation in the same way like we have applied in user table so just few new uh validations that I have applied here in is features I have applied is in the value should be either true or false and if this is not the case we'll return error with this message in the same way product images price we have applied and is decimal so this is little new here don't be worry this code will be inside my G GitHub repo you can you can take the pull to get all this code description and here I have applied e URL so if product URL should be in string and that string should match to URL so if that is not the case we'll return with this error message category and everything is are same now let's add the additional information with this table first one is paranoid so this will enable the feature of soft delete and to work the Paran not make sure that at least inside the migration you have defined deleted that even if if you don't Define inside the model that is perfectly fine but this feature used that deleted at column okay next let's use freeze stable name make it true so that this will not do the plural of this name project so this will be freezed now let's give model name here which is Project perfect now let's create the project controller now let's define a controller here const create project and wrap this function with catch as sync as sync it will take request response next we'll get the data from body so let's receive request. body const new project await project model it has a method create in same way like we did for the user now let's define all the fields here so I'm going to pause this video and complete I'll complete for you now we have defined everything title and features we'll get all these information from the body but we not get created by from the body we need to pull this information from the token so once user do the login and then they will call this route so we'll get this information from their take so later on I'm going to complete this feature just for now I have added id1 so that it it do not throw any errors otherwise it will start throwing error because this is allow null is false right now if this doesn't throw any error we could return the success from here response. status 2011 doj status data new project perfect now if it fails any validations this catch will catch the error and we could get the error from error controller so now let's check this is working or not but before that we need to define the route as well so let's go to the route and create project route. JS in the same way we defined the route for this let's just copy from here paste here delete all these and even delete this now let's create a route so I'll use router. route and let's define SL route. post method we'll use for create project I think we haven't exported this controller so we need to export this so let's quickly export from here module. exports inside an object create project then let's import here perfect now this route is not linked with AB doj let's quickly link here in the same way and this will be Pro objects okay now let's do copy paste update this file name project route and name it project router project perfect now let's run this application now let's create a separate folder inside this maros colle ction name it project let's add a request here this will be create and Method will be post now let's use the same URL but this will be different projects slash and inside the body let me it would be in Jon format so this will be the object title product image inside the array I have just passed to dummy images is featured we I think we don't need to pass this from here so let's delete it if you pass so is feature true or false that will be the job of admin I don't think so we need to do it from the user side so let's quickly fix that issue so inside the project controller if you're taking e feature just let's remove it so by default it will be false fine now let's come back here and that will be false so product image price short description long descriptions we have given product URL and category tax and we didn't pass the created byy that will automatically take let's hit so we could see here is featured false by default id1 and this is created and here we could see created by one so this is because we passed intentionally here now let's quickly check that everything is working or not so if product URL is some wrong or something like that let's see invalid product URL we see this message right so validations are working now let's quickly work on the uh user validation so this route shouldn't be public as of now if you see I don't need to do the login to call this route but if we are not a logged in user this shouldn't work we should get error so let's quickly work on those so inside the O controller let's create one more controller const authentication again it will be wrapped with catch sing it will take three thing request response next we'll do the authentication three steps the first one will get the token from headers Second Step will be token verification third step will be get the user detail from DB and add to request request object so that we could use in next middleware now let's quickly get this so let's define let ID token as a blank string now let's write a condition here if request. headers do authorization if that is there and and request headers authorization string it starts with Bearer then ID token we could get it from this this string will be something like this let me give you the example here it will be be Bearer and the token something like this so we just wanted this part of the token not this Bearer one so let's do dot split based on this space so we wanted to split this into the based on this space so this will be the index zero and this will be the index one so let's pick index one now let's apply the here if ID token is not available it's missing then we will return with the error message please login to get access now if this is not the case it means we get the token then the next step will be the verification so let's quickly do the verification here const so after doing the verification we'll get the token detail so how we do that JWT do verify it will take token so here we need to pass the ID token that we get from the headers and the second we need to pass the secret key if you remember this is our JWT secret key so token plus secret key we need to pass to verify that token is valid or not so process. EnV dot the secret key if you pass it and if it is correct we'll get the token here now if we find any issue in verifying the token or let's take an example token is not valid then we will throw the exceptions from here that we could handle inside our error controller so let's quickly add the Handler here if we throw the exception so this will be the Jon web token error and we could get it and then we'll response invalid token from here with 401 status but if that is not the case let's come back to the project controller sorry Au controller then if we don't get it error from here we'll get the token detail So based on the detail we could find the users information from the database so let's get a const press user user dot find find by primary key and from token dat. ID we'll get the ID from here if you remember that at the time of generating the token inside the payload we pass token so from the token we'll get the ID that ID we need to pass to get the user detail from the DB and this detail will add inside the request object but before that let's put one more condition here fresh then return here next new app error user no longer exist and with 400 error now if this is not the case then finally we could WR uh add token inside the request object request. user equal to Fresh user and then let's call the return with next method so this will call the next middleware now we could apply this authentication so first of all we need to to export this from here now let's apply this inside the project route so before this middleware we wanted to call this authentication middleware and let's import this so this will do the authentication if this authentications run successfully we call the next at the end so we call the next so this method will call the next middleware but if if we call this next with error object then it will skip this middleware and directly it will call to This Global error Handler so now hope you have understand the meaning of next now let's quickly check that it is working or not now if I call it please log to get the access and we are getting the error not the status and here we getting the 500 so let's quickly fix this issue why this is the case so here we didn't pass the code so the code will be 401 unauthenticated access yeah now I started be getting the status fail 401 unauthorized access now if you do the login successfully then take this token and pass inside the create let's save this and inside the headers let's apply Bearer token and pass the token here now here we could see id2 so the product is created now if we alter the token what will happen invalid token now only one thing left here now inside the project controller instead of passing this ID hardcoded let's get this value from the token const user ID equal to request. user. ID because we have added this user inside this request and we could get it the ID so now let's pass this ID inside here now let's do one more thing let's registered with a different user sign up so I'm registering with this email ID and with this detail let's send this request now let's use this token now remember that ID is 10 go to the create the token and hit the send success now here if you see created by is null actually let's fix this issue so basically I found two issue the first one we shouldn't get the null so inside the migration we forget to apply allow null here if you apply anything here we need to rerun the migration and before that we need to do the undo and also inside the authentications we didn't appli a weight here so so yeah these two issue were there now let's quickly do the remigration undo it will delete the project table the recent migration it's not going to delete the user table so you could see it's reverted this now let's rerun the migration again perfect let's run it now let's call this and here we could see it's created by id1 still we are missing an important thing here so we did the authentications and we make sure that this route will only be accessed by the authenticated user but we have three kinds of user admin seller and buyer all will be the authenticated in our application so anyone can call this route but I want this route should only be called by the seller they could only create their projects not admin and not even by the buyer so how we could protect this route from these two different types of users so we call this things authorization so we only want to give authorizations to the Sor so let's quickly work on authorization so inside the O controller I'm going to create const restrict two and it will receive user type to whom we wanted to give permissions in an array format and from here we'll return check permission and it will return middleware request response next and inside here we'll check if user type dot includes request dot user dot user type now if this is confused you don't worry I'll explain you just now so we will receive to whom we wanted to give permission so maybe like one and two so we'll receive inside an array one and two and we will make sure that the user that do the login have the same ID which is inside this array so those user will only get the access if this is not the case we're going to return error with this message you don't have permission to perform this action with 403 status and if this is the case then let's call the next method otherwise we will hang the request will not go to the next middleware fine now let's export this from here and now let's apply inside the route so after the authentications we'll apply res restrict two and we could pass the ID to whom we wanted to give permissions so they will only be able to access so for now I'm just giving permission to the seller but if you wanted to give permission to buyer let's add buyer or in that way you could add the parameter here so we'll call this method so now for now just give only permission to one and this will return this check permission so actually we are getting error because we didn't return it from here so just right after this function return this check permission perfect because this post method always receives here middleware so this is also middleware this should also be middleware or either middleware or this should return a middleware so I returned a middleware from here and this is also middleware so we call next from here to reach to this and here we check the permission and if this is correct then we call the next now let's check it let's call this so it's created successfully because we have the permission now let's change the permission for now and we don't want give permission to the sa let's only give it to user zero now we know the seller user type is one you don't have permission to perform this action so we successfully created the authentication as well so let's change this again to one fine now let's work on get all projects route so go to the project controller and let's create here cons get all project catch a sync as sync next now let's get the result from AIT project dot find all and then just for now let's return SP start S status data call it result now let's export this from here now let's define one more route so we Define the post route get route here do get this will also be protected so authentication is required for this one and then we will call get all project but for now we didn't restricted this to admin so uh like after some time we will restrict this only for the admin user but just check this is working or not so let's duplicate this get all let's change this to get now do we have be to let's call it so here we could see data is coming in an array format now let's take an example admin called this route but he don't know who is user 10 so we also want to get the user information so for that we need to work on associations so let's quickly work on Association first so go to the user model and here we will Define the association so before that we need to do something let's give a name instead of doing directly export from here const user and Export we will do at the end user and before it let's define the association you can read more about in official documentation so has many projects each user could have many projects right foreign key what is the name created by now let's define the the reverse of it as well like project belongs to user perfect and here also Define the foreign key which is foreign Key by now always remember that you don't have to do this in the project here like I have seen few people do like has many defined here and project and try to Define here then you will see the error because it will stuck in uh circular dependency so just just Define in one place either here or inside the project fine so we defined this now project controller and here find all here we will also Define the include user now let's call this route if this time we call this route you will see user detail as well here so in SQL we call it join so we did the join of two table and based on that we found the informations here now let's work on get project by ID so inside the project controller it will be very similar to what we already have created get all projects so let me do the copy paste here change the name get project by ID now here we'll receive an ID from params const Project ID p.p. idid and this ID we need to pass inside find by PK and we also give include option and the rest will be the same now let's export this now let's create the route project controller we need to define a new route router. route and it will receive callon ID and then we'll call get authentication user only can access this and get project by ID perfect now let's check this so if you pass the project ID which is two id2 here so we only get the project ID which is id2 and with all the details just a small update here we missed one condition here so let's apply the the condition here is if we don't found the result then we need to give a error message invalid project ID it means project ID is not perfect that's why we don't get the result now let's come back to the postman and here also we need to update this so instead of calling from get all let's create a separate route just update this now let's duplicate this one get by ID inside here we also need to do the beer token so token is already added now we wanted to pass the ID we could directly pass ID here or we could also create a variable ID and inside the param you can pass the value like I wanted to get one let's send the request can't find the url project one okay now let's pass two so we have some issues let's solve this okay so because we are sending the post requests let's convert this into the gate and send it now here you could see it's working if you change the ID here it will start working so the developer could easily understand that this is the params now let's work on update project project catch as sync as sync it will receive request response next now let's get first user ID from the request. user. ID let's get project ID request. params ID get all the data from body that we wanted to update body now let's first find result equal to a wait project. find by PK and here let's pass the project ID now let's check that did we get the result if we don't then we will return that the ID is invalid next with new app error invalid project ID with 400 now if this is not the case it means we get the result now let's update one by one each and everything now one by one we try to update everything result title we'll get this from the body title in the same way we did for everything now once this is done now let's get const updated result let's call await result dot we have one method save so it will update the record now we can response back to the user so let's do the response from here and we'll give them updated result fine now let now let's go back to the postman let's duplicate to the create let's name it update and here we need to pass ID as well and this method will be patch so we haven't defined the route I think so let's quickly Define the route let's first export this from here now let's go back to the project route in the same params one we will Define dot patch this also must be authenticated users authentication and then we'll call upd date project perfect now let's come back here inside the postman now let's do here so what project ID we wanted to update so let's we wanted to update two and inside the body we'll give them the name so what is the project ID 2 we have so we have title attendance management system so let's just update to the title and not others so but still we need to send all the details so let's go back to the patch side the body instead of attendance we'll give them final year project price let's update to 30 final year final project so I updated few information let's send the request fail we need the login access let's pass here beor token so we we have updated final your project now we have missed the minor conditions here so if you remember that we use find by PK and project ID so if anyone wanted to update this project they could update but we want that those who created this project can only update that so instead of find let's do find one now let's apply a we condition where ID project ID created by user ID then only this should get updated so this will work now in the same way let's define deleted at let's just do the copy paste change the name delete project it will receive in the same way it will check the condition instead of update now here we'll call the destroy so this will delete the record so once this is deleted we don't need to send them any so instead of the result we'll just send them message record deleted successfully now let's export this as well now let's define a route now let's call delete authentication is required and delete project perfect now let's check this duplicate this let's name it delete give the method delete as well and here ID I wanted to give one let's call this please log to get access let's pass the bearer token record deleted successfully so probably this is the token now if we call it invalid project ID if you wanted to delete project ID let's see what are the availables project ID we have project ID 3 which is created by 10 now let's go back to the delete now let's save this inside the params we are going to pass ID3 invalid project ID now if we pass the correct signature here if you change that to the uh token of created by 10 so this is the user token of the user ID 10 so if you call it then this time it will delete successfully so this is working fine now let's restrict this access to only to the sers they cannot get all projects okay and here also we need to apply one more condition which is where created by will be user ID now we could get the user ID const user ID from request. user. ID so this the condition will applied and then we'll get all the projects in the same now let's come back here and we restricted this only to the seller not to the buyer that's why we applied one in the same way let's apply this to all other routes so these are the routes will only be accessed by the seller not by the buyer now let's apply here as well now let's quickly check that it is working or not let's start from get all post So based on the user ID we'll get only those records that is created by 10 now if we change the login and we try to login from this let's see does we have anything for this user does this have any projects no now let's create a Project based on this this user ID so he created one now let's come back here get all and call this now here we could see one record now let's work on the seat so seed is used to add some default data into the tables so in our case we have a signup process through the sign up we could do the sign up for seller as well as for the buyer but we don't have any way to uh sign up the admin user and we don't want that admin users should uh go through the signup process we wanted to feed the admin user detail into the tables directly through the seed and Seed also have a lot of uses in testing so take an example if you're doing the application test testing then in that case probably you need to feed a lot of data related to user related to projects that all of the data you wanted to feed into your application then you will perform the testing and once your testing is done you wanted to delete it for this use cases if you wanted to go through the like manual process are you going to insert all those data through the queries no so we use cedar to feed all the data into the applications once we are done we like in the migration we run down and it will delete all the data so here you could see the example how to feed the data into the tables so let's quickly create a seed file inside our application and I'm going to give the name C2 admin user so it's created seed file inside the seeder folder here it is now let's copy and paste from the example that we get here let's come back here now let paste this and let's delete everything now we have first name last name we also have email so let's give it like admin example.com we have created and updated at this time we need to to explicitly pass this information because this data is directly going into the database it's not going through the model let's use password as well here so here I'm giving like admin atate 1 2 3 4 so as I said this data is directly going into the database this is not going through the model so whatever the validation we applied inside the model this is not going to be executed when we run the cedar file so even the hashing of the password will not happen so we need to do that hashing explicitly inside the cedar so let's do the password hashing so instead of passing the plain password directly here let's use a variable let password and then we'll pass this password into the hash and solt now let's change this name this will be user layer here also update the user and we also want to pass the user type so this is for the admin user so that's why the user type will be zero fine now let's apply the condition at the time of delete admin user value zero so it will if we run like Cedar undo then it will run this query and it will delete all the user which has a user type zero we don't want want to keep the sensitive information email and password directly here we will do this through the EnV variable so let's update here so let's use this email so instead of directly typing here let's use process.env do this and in the same way let's use for password let's apply here and we'll apply this password test atate 1 2 3 4 test and we'll pass this password inside this and then this hash password will pass here now I think our Cedar file is ready so if you want to hide all the informations you can do it uh get this information from the uh EnV file so even the developer will not be able to know that what is the admin email and their password because this em file uh at the time of employment admin will uh modify according to their needs now this is done now let's run the command which is npx equalize C DB colum SED colum all now one more thing by default Cedar don't keep track of all these Cedar files that already been executed let me quickly explain you what I'm telling you so now here in the storage there is three kind of storage uh SQL is used for migration as well as for the cedar so for the Migration by default storage is equalized so all the uh migration detail keep track inside the table and in Cedar by default is none means they don't keep track of the uh executed Cedar files so but for the Cedars if you wanted to store uh you wanted to keep track of Cedar file as well then probably you need to use cedar storage and let's go to the config now here I have already specified Ceder storage sqy so that our Cedar information will be stored like what are the cedar files already gets executed will be stored inside the database now let's run this bcrypt is not defined so let's quickly go back here and yes this is not defined const now let's run the Z command one more time hopefully this time it will execute successfully so Cedar file migrated successfully now let's come back to the pg admin and refresh this and see we have four table squal data as well so this table keep track of all these CER file that already been executed now here we must see the name of that file we could see it here now if you go to the user table here you could see we have added the admin the type is zero name is this and their password is also encrypted so this is the way we could feed the data now let's run this application now we can do the login using the admin user as well so let's grab the admin email ID and come back to the login go to the login and this time let's pass email and the password will be test atate 1 2 3 4 if this is correct we should be able to see incorrect email and password let's quickly fix this issue now actually I made a mistake I haven't saved that so it looks like the previous in permiss they haven't picked this information so I have saved now and I have saved this file as well so yeah so this mistake we need to run the undo first so it is reverted now let's quickly check that does it reverted successfully yes here you could see that admin user informations is deleted now let's rerun this Seer again now hopefully this time we should should see here the correct information yes at theate example.com now this is correct now let's go back to the login and hope this will work it fails okay because we didn't run the application now let's run it perfect now here we could see the admin token woohoo congratulations so we are almost done with the projects so we just need to add add few more routes and this will be the same process that we learned throughout this video so let me quickly show you that I have created a new controller user controller so this controller will only be accessed to the I'll give this route access only to the admin user so only admin user could call this controller and here I wanted to find all the user details and we wanted to return to the admin but here I have also applied the condition that this uh result should should not include the admin details because admin is calling this route and we don't want to give this their detail also inside the list so that's why we excluded this using the SQ eyes and you need to import this from the SQ eyes package and it has a operator not equal to so we have different types of operators you can look into the documentations now here we excluded the attributes password we don't also want to send the password in the list and then we return from here and we Define the user route here and we provided authenticated and restricted to zero and then we call this and this is has a get method now let's come back to the postman here I have already created a folder user inside this I have created a request get all user and here you need to pass the admin token then only you'll be able to get this data if you pass like some other user details take an example we want let's get this user detail like test let's do the login test 1 2 3 incorrect email and password let's do test atate 1 2 3 okay test 1 2 3 now if we try to call this route with this token this will not work you don't have permission to perform this actions and we getting this message so yeah so thank you so much for watching this video till the very end please like share and subscribe my channel
Info
Channel: Technical Babaji
Views: 14,096
Rating: undefined out of 5
Keywords: technical babaji, tarique akhtar, rest api, web development, express js, node.js tutorial for beginners, express js tutorial 2024, node.js for beginners, Build a complete REST APIs, REST APIs, Postgres, PostgreSQL, sequelize, sequelizeORM, Connect to a Postgres database using SequelizeORM, Handle user authentication and authorization, REST APIs in Node.js with Express, Postgres and SequelizeORM, Learn sequelize, Learn sequelize ORM, Complete rest api in nodejs, node js tutorial
Id: QoLqMDSBZAs
Channel Id: undefined
Length: 129min 29sec (7769 seconds)
Published: Mon Feb 19 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.