Build Rest APIs in Next.js 14 - Middlewares | Protected APIs | MongoDB | Database Design

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi guys welcome back to another video next js14 in this video I'm purely going to talk about apis building back end building rest apis so if you want to learn front end because this is what I'm not going to be talking about in this video I've already created almost 50 videos on NEX gs14 nextjs 13 both varians uses app directory so you can watch and learn pretty much everything that you would need to become a good nextjs developer using App directory so do subscribe my channel and like my video so in this video I've already created a new NEX js14 project it contains nothing new I've not changed anything and you can see that I'm already running this project so in this video I will be creating a new folder structure I'm going to show you how you can protect your back end and also how we can connect our backend apis with the mongodb database how we can create models like user model notes model add multiple relationship between those models and and how we can perform queries to fetch the data perform Crow operations like get post patch or delete operations and finally I'm going to be testing these apis using Postman so this is going to be a very important video if you want to become a full stack developer using purely nextjs and also I will be talking about middle Wares which is very important topic so let's get started I'm going to stop my server let me clear the terminal and we have this app directory which is by default created when we create a new next js4 project so inside this app directory I'm going to create a new folder so this is going to be called API we cannot change its name so all the API routes hold backend should exist within this API folder and inside it we can create different more folders so if we want to create API let's say the Local Host column 3000 SL API SL users so we want to give the same name to this folder which we want it to be a part of URL for the rest API so I'm going to create / API SL users and inside this users folder there is a predefined file name provided by nextjs we cannot change its name this is going to be route. TS so this route. TS is automatically going to get executed the code inside it when we try to execute the API on the URL / API SL users so inside it we can actually export the get request this is the pred find function name we cannot change its name so we can have the arrow function and inside it I'm just elaborating you guys that how the apis are constructed I'm going to be modifying it once I proceed further once you get to know that what the folder structure we are going to follow to create apis so inside it we can actually return new and then next response from the next server and inside it we can actually this is my first API and I have returned this from this get request now I'm going to run my server again I'm going to run my next yes project and let's go to our browser let's refresh it so that we know everything is going well so now what I'm going to do is I'm going to execute this API since this is a get request get request can be executed on browsers directory all right because we don't need to pass the body or something like that so I'm going to write slash API SL users I'm going to hit enter here you guys you can see that this is printing this is my first API so this is actually API route the get request which we have executed how simple is that we just need to define the same folder name which we want it to be a part of URL so now I'm going to start off connecting my project with the Mong DB so first of all I'm going to create a new file this is going to be EnV which is going to store all the environment variables okay so here first of all I'm going to create DB URI equals to and now I need to go ahead and open up Atlas uh website uh you can go to cloud. mongod db.com and it will ask you to sign up with your account it will ask you to create organization once you do that uh you need to create a new project I've already done that that's why I'm looking at uh these a lot of projects which I've already created and I'm going to click on the new project and here I'm going to create the project name so I'm going to name it next 14 rest API all right so let's click on the next uh leave the project owner because uh I'm creating project myself so I've clicked on the create project button so it's going to create that and after after that I need to set up few things I need to uh create the username and then the password all right so let's see how it goes now it has created my project now I need to click on this create button and uh this is going to create a cluster so for now for the tutorial purpose I need to click on this free version and uh you can click on this any provider you can click on the nearest region and uh we can change its name but I'm going to go with the same one and I'm going to click on this create button now so it's going to create the cluster uh after this it is going to shortly going to ask me so here you can see that it is giving me the password I need to save it somewhere because I'm going to be using it in my project so I've saved it I'm going to click on the create user so it has already created and now I'm going to add my IP I think it's already added um so here U this IP refers to my internet connection means that the apis which we are creating can only be accessed with this network if we want to allow it um from everywhere we can do that which I'm going to show you after creating this so I'm going to click on the finish and close so go to the overview so it's going to take some time it's going to process the uh settings which I have set uh so once that is done uh first of all before going to Let's click on the connect button and click on the drivers and this is the URL which we need I'm going to copy this URL and I'm going to paste it over here you can see that and uh the password which I copied earlier should be replaced here so I'm going to copy that password which I've already saved in my notes so I'm going to paste that password over here and after that I don't need to do anything all right so let's close this EnV file let's close this one let's close this one and uh after that let's go to this mongodb and I'm going to click on the network access uh selecting that particular cluster and add IP address and access allow from anywhere so I can click on it and it's going to add 0.0 means that this particular database can be accessed from anywhere in the world click confirm so after this video I'm going to remove it because I don't want you guys to keep on triggering my apis on the same password and username which I have created so it's going to uh create this uh so we can leave it as it is now let's come back to our code in this code first of all I'm going to create a new folder which is going to be called Leb all right so in this lip folder I'm going to be creating a new file this is going to be db. TS all right before writing any code inside it I'm going to install Mongo's package so in the terminal let me clear this out so it becomes clear to you so npm install and I'm going to write so this is a very important package uh which we can use to create models as well as to connect to mongodb database all right so once it's getting installed we can start importing it in this file so I'm going to write mongus from mongos all right so after this we can bring up that particular URL which we created in EnV file so I can write the DB URI equals to process.env uh do mongodb urri all right so this is what I have imported now uh we can directly write this command but I don't want uh to connect directly I want to create a function so this is going to be the connect equals to async and then I'm going to create a ready State since we are going to call this connect function from every API I want to check if the connection was already established I don't want to reestablish the connection with my database so I'm going to check it with my connection State equals to mongus dot connection. ready State all right so first of all it gives us four or five I think different values so I can write connection uh connection State I need to copy this one okay connection state equals to 1 if it is one it means that we are already connected so we are simply going to return from here let me log this out as well so already connected all right and after this I can simply return let me copy this if condition and I'm going to check it with two so it is it is going to show me the connecting all right and after this I'm going to start connect to the database if both of these conditions fails it means that uh we need to connect so I'm going to write mongus do connect URI which we have fed and then DB name we need to define the DB name let's give it the rest API next4 all right and after that uh we can simply Define the buffer commands uh false all right so it is showing me this error so let me hover this out so argument of type so it it is considering that this particular variable can be undefined sometimes okay but we know that uh this can never be undefined because we have successfully defined over here so just to let it know that we are 100% sure we can add this exclamation mark that it will never be undefined okay so after this once that is done uh we can simply write connected all right so then let's add the cat block as well in case there is an error there is some network error or some other error uh that cause disconnection so error in con connecting to database let's also log the error as well all right um and also let's throw new error error connecting to database all right uh this is just a message all right so we are done creating it if we go up we actually need to export this connect function because we are going to be accessing this fun function from outside this file from the API routes so finally I'm going to write export default connect so we are done with this file uh what is that actually I'm going to remove it so I'm going to close this DB file I'm going to close this EnV file and inside this lip folder I'm going to create another folder and this is going to contain all the models so I'm going to be creating few models which is going to be user model and the notes model and also I'm going to create the relationship between these models so first of all I'm going to be creating this file user. TS and also I'm going to be creating notes. TS so in this file I'm going to create a user schema schema means that what are the different properties this user is going to have for elaboration purpose I'm going to add few properties which is going to be email username and the password I'm not going to implement the full authentication system I've already created a lot of videos on authentication even using the next o OJs or clerk authentication you can check that out this is just for elaboration and I'm talking about rest apis in this video only so I'm going to first of all import and I need to import the schema I need to import the model I need to import the models and this is going to be from mongus all right and below this I I'm going to create a new and I'm going to name it user schema let's create a new object for the schema class which we have imported above and let's add the email and uh this is going to be one of the type uh one of the property for the user and this is going to be off type string and this is going to be required and this is going to be unique as well okay so once we are done after this U I'm going to create a username equals to type string required true um and then the unique true and after this I'm going to have the password this is also going to be string and the required true uh so if you are curious what uh extension of vs code is actually suggesting me the content is actually the tab n which I'm using you can install this extension in your system in vs code uh and that is going to help you out while writing code so now I'm going to write um const user and first of all I'm going to check if models dot user already exists otherwise I'm going to write the create a new model let's add the equal to sign as well over here so inside uh this model um actually I need to write like this so user user schema which I have created above let's export this out export default user all right so that's pretty much it we need to do we can have more properties uh for this just to let you know guys that I have created 40 plus videos on node Express mongodb and that is an advanced course if you want to learn Advanced schema creation using the mongos you can check that tutorial series on my channel node Express mongodb tutorial series crash course you can search that out on my channel now we are done with creating the schema for the user let's go open this up notes and I'm going to create the schema for the notes as well so first of all let's copy this line and then I'm going to create note schema equals to new schema uh and inside it it is going to take few properties title and then the type equals to the string this is going to be of type string this is going to be required let's add the description and this is going to be of type string uh I don't want to keep it required so let's keep it like this now the next property is very important this is going to be relationship with the user so I'm going to give it the type and the type is going to be be the schema. types doob ID and then I need to Define its reference reference has to be the name of the model which we have already created so I will be creating apis that will actually allow us to fetch the notes only those notes which belongs to a particular user the users who have access to their own notes will be able to perform crowd operation for only those specific notes using the get put post or delete requests so after that I'm going to create the note equals to models. note otherwise I'm going to create model and let's add the note and then note schema let's export this out now uh so we are done with this model we are done with the both the models let's close these files we are done with this setup now it's time to go back to over API directory and start creating apis using this uh schema models and this configuration for the DB which we have added over here so this is our route. TS file which I already created I tested that out first of all I want to structure my API folder structure so I'm going to create a new folder inside this API and it's going to be wrapped inside this parenthesis wrapping it inside the parenthesis means that we don't want to include it as a part of the URL structure for the apis we are just creating this folder uh to structure over code to look it better so the reason I've created and named it Au because I want to create all the authentication authorization related or user related apis should be added within the Au folder so I'm going to move my users folder inside this o folder as well all right so now this URL is going to be same/ API SL users this is just for structuring if there is any other thing let's say forget password or reset password or profile API then the same uh folders can be added within this OD folder now we have this route. TS file added over here I'm going to create and modify this get request uh so I'm going to fetch all the users which exist in the database currently there are no users exist in the database I just want to verify if the connection to database actually successfully done and we are successfully fetching the users from the database which are zero currently but it should return empty array okay so first of all at the top I'm going to import the connect function from the lib DB which we have created all right so inside this get request I'm going to start off with creating the tri block and let's wrap it with the catch block so error like this so inside the try uh since this is the async function so I'm going to write await connect all right this is going to make connection to the database uh and after this I'm going to fetch all the users so this is going to be const users equals to await user this is going to be coming from the models user it has automatically imported at the top and user do find this is going to find all the users and store it inside this particular V variable these are the pre-built functions provided by mongus uh you can refer the documentation if you want to know more about that and after this it is going to return the response um in the form of Json so I'm going to write json. stringify users and in the second param we can actually return the status 200 as well all right and after this we can also return uh the uh this response and this is going to be with the new keyword sorry all right so this is going this is not going to be Json this is going to be like this and error in fetching users uh let's also concatenate the error and also let's add uh the status equals to 500 in case there is an error all right so now I'm going to test this API which I have modified let me run the project in the terminal uh also save this file and in the browser I'm going to hit the same URL which I hit before which is going to be/ API SL users so let's go to the Local Host uh this is giving error maybe because of the caching let's hard refresh and yes you can see guys it is returning empty array and if we see the terminal you can see that it is showing connected means that our database have been successfully connected and that's why it is returning empty and if we go to our database uh let's go to the collection and it should automatically create the users model within this database name um you can see that it has created database name which is coming from this lib folder which we provided the name over here and also it has created the name of the model as well this is uh actually showing that we have successfully uh connected to database and this user is showing the result zero all right so now I'm going to create the post request this is going to you can say a sign up for the user before moving forward I just want to let you guys know that if you want any development services in web development mobile development from me you can contact me on LinkedIn I've given the link in the description of this video and also I have the WhatsApp Channel with the same name programming with Omare I've given the link of that channel in the description of this video do check that out and do follow my WhatsApp Channel as well so let's get started and create our post request so this is going to be in the capital letter post and this is going to receive the request so request and this is going to be of type request and we can have the response as well uh we don't need that because we are using the next response class which we have already done so this is going to be equal and then the arrow function actually all right so in this first of all let's add the tri block and let's add the catch block again with the error like this so first of all what we need to do we need to receive the data which will be coming from client client can be the same application which we can create the component within our app folder uh or it can be the postman it can be angular JavaScript or any third party external front-end application this is what the client means um I'll Will Show You by testing on the postman because I'm not going to create any front end in this video so try and this is going to be received body await request do Json all right and also this is going to be an async because I'm using a weit keyword over here so a wait and async means that until and unless I'm not able to get the data using this function it will not move to the next line of this code okay I need to have the data proper data after this I'm going to connect to the database okay and then I'm going to create a new user with the data which is coming from the client and this is the Syntax for that user is the model uh which is already added above I think yes it is already added and this is going to be passed with the body this particular class actually require the Json data for the body and when we use this function to get the data from body it is automatically converted in the form of Json so we don't need to convert that body data uh body data means the model data this email username and the password it is already converted into the Json while we are passing in this class okay so after this I'm going to write a built-in function which is going to save save is going to store the data for this user in the database it is automatically going to add the ID and the time stamps and all these things okay and um now this is going to uh show me this hint the tab n this is awesome uh return new next response Json let me verify that it is returning uh this thing user and we can actually return the Json as well so message user is created and then new user uh user colon new user uh this is going to be this new user all right so I need to close this as well okay so this is going to be 21 which is the success response and then inside the catch block I don't want to explain it uh again which I've already done above in the get request so if there is an any error it is going to show me this things all right so I'm going to save it uh keep the server running in the terminal and now I'm going to open up the postman Postman is an awesome tool which we can use to test the apis we can document the apis we can create environment variables all right so I can create different folders uh this is what I have created rest API tutorial I can create a request I can add the request for the get so get users let me first verify by clicking on this okay U and I'm going to click on the center you can see that it is returning uh empty array same as the browser it means that it is working fine now let's save this and let's create another request so let's right click on this folder and I'm going to click on the add request uh and let's change its name uh create user okay and also change its type which is going to be the post request and uh I'm going to paste uh the name Local Host colum 3000 it's showing me these kind of URL because I was already been testing these apis before creating this video so API SL users it's going to be on the same URL because uh this refers to the same folder structure but the method is different okay and now you can see that here it we actually implemented to pass the data inside the body okay so I'm going to click on the body and I'm going to click click on this raw and I'm going to click on this Json okay so here I need to give the data so let's verify what the data we have here so we have this user we have email username and then the password all right so first of all let's add an email uh om 1@gmail.com any random email um and then I'm going to write username and this is going to to be the Omare and then we can write any password to it make sure you add the exact same Keys uh so let's add this random password all right so let's click on the send all right so it is showing let me click on the Json user is successfully created and this is the data returned from the created user we can verify that and I'm going to click on this Refresh on my database and let's see if we have actually data added over here or not yes guys so word data for the user is successfully created in the database as well uh all right so we can actually create the second user as well so let's add the um mza um let's change the password as well let's click on it and this second user have been created as well and we can use this API to verify all the users and let's go to the get request let's click on the send and here you can see that there are two users exist in the database which are successfully created now I'm going to create couple of more apis one is to addit the data for the user and also to delete the user after that I'm going to be creating apis for the notes which is very important because note has a relationship with the user okay so now I'm going to go to the route. TS and I'm going to create a new request and this is going going to be the patch all right so let's come over here so exort const patch all right like this and this is going to have an async keyword as well and inside it it is again going to have the request all right so inside this patch request I'm first going to add the TR try block just like the previous thing try uh no I don't want that and let's add the cat block as well all right so inside the tri block first of all I'm going to connect to the database uh we can actually fetch the data from uh the body first of all if we want uh so let's do that so first of all we have this body of weight and then the request. Json okay and after this I'm going to get this data I'm going to get the user ID and then the new usern name equals to body this user ID is refering to the user which needs to be updated and this is the data for this particular user that needs to be updated inside that user so both the things will be passed from the postman from the client actually okay so after this let's add click on the connect uh this is already added here I think I clicked on the tab I'm just going to remove it all right so after this first of all I'm going to verify that if this user ID is valid or not if this user ID actually exists or not okay so I can do that first of all let's go at the top and uh we have this predefined object ID uh whenever any new document is created in the mongodb database it has an ID whether it's user whether it's nodes uh that ID have a specific formate and mongodb gives us a function that can be used to check if the ID is valid or not so require I can write the dot types doob ID okay so let's go down here inside this connect I'm going to write if not user ID user ID should be exist because without knowing which user it is we will not be able to update its data okay so user ID or new username okay this username is not the key this is the new user okay uh now I'm going to add this if any of these does not exist I'm simply going to return an error all right so this is returned and after that I'm going to check if the user is valid or not ID is valid or not so I'm going to add it like this so here you can see that the types which we can import it from mongus at the top you can see that it has been imported and uh this is validating if the user is valid or not so types object ID user is valid uh or not okay so after this we also want to check if the user exists in the database or not not if it exists then we are going to update it so these validations are very important guys so updated user equals to await user. find one and update it has these functions find one and delete replace and update this is what I'm going to be using update so we are going to pass an ID okay so new object ID which I have created Above So user ID this first value referring to this find function that this is going to find a particular user the next value is going to be the username okay username uh this the username is something which I'm going to change from the client side okay uh we can pass more Keys as well but this is just for elaboration uh I'm just passing the username that needs to be updated I'm not going to change the email I'm not going to change the uh password in this particular API but you can do that if you want and then I'm going to write new equals to true this is going to return a new object by updating it all right so after this I'm going to check if not updated user means that it is not updated it did not find or if it was not successfully updated in any case uh U the most of the case is that it did not find that particular user so I can simply return a message uh with the 400 so I'm just going to copy all right and uh I can simply write user not found or didn't update user successfully any message you want to write uh so this is going to be updated once all these conditions are verified we are going to return a success response that user have been updated successfully so I'm just going to Simply return this response username have been updated successfully um and again I'm simply going to return this error message inside the catch Block in case up there cause any error because of internal issue all right these validations are very important so I've created this patch request now let's go to the postman and I'm going to create a new request add request and uh let's name it update user so it it has been saved uh and uh also I'm going to just copy it let's paste this and also I'm going to change the method type patch let's click on the body let's click click on the raw let's click on this Json and inside it I'm going to pass the data one is the user ID and other one is the username so this is how we have implemented our API all right so within this object I'm going to write the user ID this is going to have this ID and then this new username this is going to have a new username let's verify these names this is the user ID and this is the new username all right let's first give the wrong user ID okay and um new name okay U and also we can set the headers in our post request wherever we are sending the body we need to set uh this one the content type is already set that is fine uh by the postman okay let's go to the body and let's click on the send okay you can see that it has actually return the invalid user ID uh this is where it is actually returning because the user ID is not valid let's go click on this you get users and these are all the users which we have in the database and let's copy one of the ID from here let's try to change the name of the second user let's copy it and let's give the correct username let's click on the send and yes it has actually giv us this username have been successfully updated and this is the new name okay let's click on this get users and let's try to verify this all right Json and this is the new name it means that our patch request is working perfectly fine and now we are going to create the delete request in our route folder let's try to close this up uh so that it becomes clear to us okay so now export const delete equals to async and then we have this request we have this uh request class name arrow and then like this all right so now in order to implement the delete I want to explain you one thing previously we have been fetching the user ID from the body I want to show you that how we can fetch the user ID from the URL from the query parm uh or you can say a search PM Okay so Let's uh click on this thing uh try and I'm going to write the search params equals to URL and then the request. URL okay this is going to give us uh an option to get the data search params and then we are going to write the cost user ID equals to the search params doget and then the user ID so it's giving error let's hover over it property search perm does not exist URL search param actually it's only URL yes the error is gone now and uh there is some kind of error because we have missed this catch block all right so now we have got the user ID from the search param from the URL and now first of all I'm going to verify if that particular user exists in the database or not because if user is not already exists we are not going to delete that because it doesn't already exist uh so I'm just going to add the same line of code which I added above if user does not exist user ID is required this is an invalid user ID okay and after that I'm going to verify if the user ID is valid or not with the same kind of code which I added above types object ID is valid um so this is going to give us an invalid user ID error and after that once these conditions are verified we are going to write await connect and await uh first of all uh I'm going to delete all the notes which are associated with this user but I'm going to do it later on once I will start implementing the notes all right so const deleted user equals to await user. find by ID or delete like this and let's try to give it types doob ID user ID okay so once that is done uh we are going to check if the delion is successful if or if user is not able to found with this user so then we are going to give us this message user not found actually above error that we did over here we actually checking if user ID exists or not we are not checking if user exists here we are checking if user exists in the database or not okay so this is going to delete this is going to if it is successfully done then we are going to Simply return a success response that we have successfully deleted the user from the database um so return success response user deleted successfully and similar to the above requests I'm going to Simply return the error message within the catch block as well okay error deleting user uh all right so now I'm going to go ahead to the postman and I'm going to add a new request add a request and I'm going to change its type to delete let's also try to change the name for this request delete uh user let's save it and uh now you know that I need to pass an ID in the URL not in the body okay so let's try to copy the URL from here and let's try to add it and uh first of all let's try to add the user ID uh like this user ID equals to let's try to add the wrong ID for now let's try to send invalid user ID fine let's click on this get users let's get the correct user ID and I'm going to click on the Json let's try to delete this second user uh to verify if it's successfully working let's pass it over here and let's let's click on the send and see user deleted successfully which is fine and uh let's close this up let's verify if user is deleted from the database and I have clicked on the send request to get all the users from the database and yes we have deleted that second user and we can verify that from this database as well um let's try to refresh so here you can see that it only contains one user which is perfect now it's time to go ahead and create over notes API routes so for notes API let me close this file I'm going to create another folder inside the API route API folder actually and I'm going to create a folder dashboard within parentheses uh because notes will be a part of the dashboard there can be settings API routes there can be reviews API routes so all can exist inside the dashboard uh within the parenthesis this will not be a part of the URL I'm just structuring my code accordingly and inside it I can create the nodes and inside it I'm can create the route. TS file and it will contain get put post delete all the crud apis for this particular note all right so first of all I will be adding uh importing few stuff at the top next response connect and the node the types and then the user okay and after that I'm going to to create export const get async and then the request of type request Arrow function and like this all right so here um let me click on the tab so we can have uh these things so initially it is showing me uh to get the notes um I'm going to keep it what the tab 9 have assisted me but Above This connect I'm going to receive the user ID because uh the way I'm structuring my apis for the notes is that only those notes should be returned which belongs to a specific user which is passed from the client side client will be passing a user ID that can be your front end application or that can be Postman a user ID can be of a logged in user okay uh which is not going to be a part of uh or a topic for this video video but let's say you are logged in and you have a user ID you will be passing to this API and only specific notes for that logged in user will be return okay so here first of all I'm going to give the search params and uh this is going to be from the url request. url all right and then I can get the user ID from the search param get user ID all right and now first of all I need to to check if the user ID exists or not and if the user ID is valid or not initially in this file I separately checked the validation and the existence of the user ID but I can combine that here by adding the or operator okay invalid or missing user ID if user does not exist or if it is invalid then I'm simply going to give a message invalid or missing user ID after that we can connect this which is is already getting done okay and uh after that I can find that particular user okay um check if this particular user ID which is being passed from the client side actually exists or not okay and for that I can use the find by ID function so con user await user do find by ID and then the the user ID okay and after this I can check if this user exists or not in the database all right so if it does not exist we are simply going to return an error message that user does not found I'm just checking all these things I'm just explaining you that these validations are very very important uh for the quality and for the performance of your app so once that is done now I need to find specific notes for that particular user whose ID is being sent from the client site okay so I can write the con notes of wait note. find and here I can write the user uh and then I can write the new types doob ID user ID okay so uh let me remove this line as well and then it is simply going to return these notes the notes are going to be fetched for this particular user whose ID is matching with the ID being sent from here all right uh and then error in fetching notes which is being sent all right so now we are done with creating this route now let's go to our uh Postman and I'm going to create another uh request here uh like this and add a new request okay so this is going to be get notes I'm I've changed its name and this is going to be the Local Host SL API SL users I'm going to give it the notes uh let's first try to fetch the notes uh directly let's click on the send invalid or missing user ID yes user ID does not found and then I can simply write the user ID let's give it the invalid it's going to give me the same now I'm going to give this user ID which is being added over here uh and let's send and now it is returning empt array because this particular user have not created any notes this is fine now we need to create the post request API which will be creating the new notes and the for that creation process for the notes again I will be using the user ID because for creating the note I need to pass this user ID property while creating a new note okay so let's go ahead and let me just close it like this so it becomes clear to me and uh now uh I'm going to create a post request below so I can start off by writing export async uh well I can write uh post like this I can use the arrow function we can use other um functions as well so post async request of type request Arrow function and like this so inside it first of all again try catch is must for handling errors all right so that is added so inside the tri block what we need to do first we need to get the user ID because for creating a new note we need to have a user ID against which we want to create notes okay this this user can be of uh can be related to the logged in user or any other relationship you want to make after this we want to receive the data for the new node and that data is the title description if we go to this schema for the notes we have title and the description and obviously the user ID which we will be passing while creation of the notes for getting the data for the note we can fetch it from the body and I have already shown you how to get the data in my my users API we can get it using request. Jon body and the body is giving us the title and then the description okay uh and after this I'm going to check if user ID exists or not and if user ID is valid or not just like I've already done in my get request user ID existence if it is valid or not okay um I'm just quickly moving further because I've already explained you these things I don't want to waste your time uh listening me or watching me just saving my time copy pasting these things and after this again we need to connect to the database uh for processing so uh after connecting to the database we need to check if the user actually exists in the database or not okay this is very important step user exists in the database if not user not found if user is not found uh it means um user ID is not passed from the client side and if user IDE is not passed from the client side means user might not be logged in user is not authenticated can be any reason then we will not we you should not actually create the notes for that so that has been said so after that we need to create a new note so new node equals to new node and uh this is going to receive the title coming from the body this is going to receive the description and then the user ID which is of type this user ID okay and this is going to create a new Noe once that is created I need to save it new note Dove okay so once that is done I'm going to return a message along with the new Note data this is going to return and also let's add the error message as always this is very important so our post request is ready now and um now it's time to go to the postman and uh I'm going to add another request and this is going to be a post request this is going to be Local Host column 3000 API SL notes and question mark user ID uh let's give a wrong user ID and also um its header should already been set like the content type uh application SL Json okay this is what it does if it's not uh uh we can actually add that it's not already added but we can go to the body and we can click on the raw and then the Json this has been set now let's go to the headers uh it's not added yet but if I start adding like this let's add the title uh Note One title and then the description this is going to be Note One description and we don't need to pass a user ID user ID is being fetched from this uh route now I'm going to click on the send so it is giving me an error that invalid or missing user ID so we have this get users let's fetch all the users we have this one only user and uh we can go and give the correct direct user ID okay let's click on the send note created all right guys so we have this one note created let's create another note against the same user okay Noe two title Noe to description let's click and this is the new Note have been created now let's get all the notes against the same user ID send and now you can see that this particular user belongs to this uh note and uh I'm going to create a new user um let's see three and uh I'm going to give it um jam and I'm going to create a new user now let's let's close it let's save it and let's close it let's get all the users now and uh this one is the new I'm going to use this ID now to actually create a new note this is going to be the note three and this is going to be the note three so let's create that note and this note have been created now um if I get all the notes let's see and here you can see that only two nodes are returned but actually there are three nodes created if we can verify it uh from this database mongodb uh you can see that notes have been added and there are three notes actually added over here am I able to uh move it up no I'm I'm not so you can see that there are three notes but here we have two notes because we have this particular user ID being uh added over here now if I try to add the first user ID the second one actually uh this one and uh let's try to update that let's send and now you can see that only one note is returned because we have actually passed the one user ID awesome so we are done Val validating with this user ID and same kind of things can be done using the patch and delete note uh I'm quickly going to do that um and uh so let's get started so this is going to show me the patch request like this so for updating the data for the note we need multiple things we need the user ID coming from the params uh we need the note ID as well that this particular note and this data for that note needs to be updated and also the data the new data that needs to be updated for that particular note whose ID is being sent through the body we can send the note ID U from the body and we can send the note ID from the URL param as well it's up to us uh but uh I'm first going to add the TR catch block here let's quickly add that um like this and inside the try first of all let's get the data for the note um I'm receiving the note ID title and the description through the body okay and then I'm going to receive the user ID through the URL param so after this I'm going to check if the note ID and note ID is valid or not using this condition just like I have been doing it for the user ID this is is very important and also same things I need to do for the user as well if the user ID is valid um and actually exists um and then after that um I'm going to connect because this is how uh we are going to connect with the databases okay so now I need to check if the user exists in the database or not this is very important all right and then I'm going to to find a particular note whose ID matches with the ID which is being passed from that body okay because first I need to find the particular note uh using this note ID then I will be able to update this titles and then the description okay so below this I'm going to add that check so here you can see that I'm using the await note find one I'm passing the note ID and passing the user ID because if you remember when we create a new note it also have that user property along with it okay so if both of these matches then I'm going to return the note okay ID and then the user you can see that the properties are matching underscore ID and this user if the node is not successfully fetched against this note ID and the user ID then I'm simply going to return an error message okay these validation again guys are very very important all right and after this this is something uh where we are going to update the data updated node equals to the await node find by ID and update first of all I need to pass the node ID then I need to pass the title and the description this note ID is going to find this node title is going to gets updated uh update the data for title and description and this is new new object is going to get returned okay um if that is done successfully then we are simply going to return uh updated note yeah updated note all right so I hope that you are understanding I'm not wasting time because I've already explained these things things um so patch is done now let's try to update a particular note with the user ID so let's close all these things first of all let's get all the notes first of all so I'm going to copy this note ID first of all let's try to add a new request let's try to change it to patch and let's try to add the Local Host colum 3000 SL API slash notes question mark user ID equals to and now I need to pass a specific user ID um and uh then I need to pass it in the body as well so let's give it raw and then the Json and inside it I need to pass the updated title I need to pass the updated description and also I need to pass the note ID if we go over here we know that it should be coming inside the note ID from the body okay all right so now uh let's click on this I'm going to update this particular note so let's add the note ID and uh let's try to save it and we have this user ID U I'm going to update the title so node 3 title node 3 description let's try to add this one updated and also description updated all right um let's try to uh do that now let's try to send note updated all right guys um and this user actually uh created this particular note the ID which I'm using over here all right so let's see we have this updated and if we get all the notes let's try to send let's try to see and you can see that it is updated successfully so our patch request is working fine now the last request we need to add is the delete request after that I will show you how we can add the dynamic route for example uh we want to have a dynamic param for example noes here we have the dynamic URL Dynamic node slug um like my first node this is not a cury param this is the dynamic value and any any value can exist over here and uh using that Dynamic value I will show you how we can get the data for a single note okay not all the notes after this I will talk about uh protecting our whole back end using middle Wares and how we can add middle Wares to specific number number of apis so let's add the delete note request now so I'm going to write export con delete async request so try catch error like this so here uh what I'm going to do is I'm going to receive both the note ID and user ID from the search param from the URL like this okay the reason I'm getting the note ID and the user ID note ID is the one we need to detect which note needs to be deleted and also the user ID we want to make sure that the user who created this note who is the owner of this note should be able to delete this note any other user should not be able to delete this note okay so again we need to check if user ID exists note ID exist and user ID valid note ID valid so we can add these kinds of checks which I have already shown you in above requests as well okay um after this we are going to connect to the database okay after this I'm going to check if user exists or not okay in the database this user uh if not exist we are going to show this message um and U after that we are going to detect if a particular note exists in the database not whose note ID and the user ID matches with this one which is being passed from the client side okay this step is very important okay so I'm going to add this line so first of all I'm finding one with the ID of note and the user ID and if note is not found it means that note not found or does not belong to a user okay so once that is done I'm going to find a particular note with the ID and also delete this thing all right uh and then I'm simply going to return a success message that the note have been deleted successfully and also I'm going to add this thing over here all right so let's move here I've already added this request and it is going to have this API sln notes question mark user ID and also it has this node ID and we can also see all the parms through the parms tab over here all right um so uh what is that beer token I'm going to click on the no o we don't need that for now U and now uh let me send this okay user not that is fine uh this is where we are actually detecting so what I need to do is I need to first get all the notes uh for a specific user let's try to get all the users first so let's try to get the noes for this first user let's get noes like this and these are all the notes belong to that user let's try to delete this note delete note I've added this all right and now if I send this it's going to show me the same error because the user ID is wrong so let's try to copy this ID add over here let's try to send node deleted successfully now let's get all the notes now you can see that a particular Note have been deleted belong to this user and we have only one note left for that user now it's time to go ahead and create a dynamic route to fetch a single note using that Dynamic route ID so for creating a dynamic API route I'm going to create a new folder inside the dashboard inside the notes I'm going to create a new folder and I'm going to name it note within the square brackets square brackets means that this particular folder can take any number of alpha numeric values inside it so the API would be SL API slash notes slash anything okay and inside it I'm going to create route. TS all right so first of all I will be adding these Imports which are required and uh now I'm going to write the export cost get request and this is going to be an async operation and this is going to be the request and then the request and we need to have a second param because we need to get the value from the dynamic param which is coming from the URL this is not a query param question mark this is the part of the URL so this can be done using the context of type params of type any okay so inside it we can get the note ID like the const note ID and context params note okay I need to add equal sign over here this note belongs to the name of this uh keyword within the square brackets okay you need you cannot change it needs to be matched now whatever we send / API notes ABC ABC will be received in note ID okay this is called the dynamic route now let's try to add the try catch block okay like this all right so inside the try um along with fetching the note ID um I want to have a check for the user as well because only u u allowed user should be able to get a single note as well the user who created this note should be able to access this single note so again I can actually get the user data from the query parm like this and uh after this I can check if the note ID or user ID actually exists or not like this just like I've been doing before um and after that let's connect to the database uh once that is done we need to check if user exists or not in the database and we can also check if uh uh if the note exists or not which we are going to detect just now so find one with the this ID of the note which is being fetched from the dynamic URL and also the user ID who have access to it so this note if belongs to a specific user who created it and this note which is coming from the u perum u have have this ID okay so once that is added we are simply going to return the note and uh if there is an error we can simply add this one all right so that is done now let's come back to the postman I've already created its request and initially there were no URL exist that's why it's showing this error now see this URL okay it has this is not a cury param this is the dynamic value and it is refering to the note ID because this is how we are fetching the note ID we need to give it the correct note ID so I'm going to get all the notes first of all and uh this is the note ID I'm going to get this one let's see um this one I'm adding over here and user ID is the cury param so I can first let's give a wrong user ID user not found um now let's let's give the correct user ID from here so which is the part of the cury we can update it from here as well let's send and now you can see that a single node is being fetched U using the dynamic URL this is perfect now we are done with creating all the apis which were uh planned for this video now it's time to talk about authenticating and protecting the whole back end like u in case that uh you have deployed your backend and even if you have to use your backend apis in your front end application then you should have a token which you need you can pass in the headers uh using that beer token you should only be able to access that um all the whole back end this will not be a real token I'm not going to be using I'm just storing a constant value for the token but you can have your um Dynamic JWT token if you want so that can be done using the middle Wares in nextjs uh so so let's get started first of all I'm going to create a new folder here middle Wares okay and inside this middle Wares we can have a more folder uh let's say the middleware for apis only so I'm going to add the apis all right so first of all I'm going to create a new file and I'm going to give it the Au middleware dots let's close these files uh so this has been added now there is one another file which is built in in nextjs and we cannot change its name uh this file is very important and I'm going to be importing o middleware uh I have missed spell it this is O middleware like this okay so first of all let's come to the Au middleware so let's export a function and this is going to be the Au middleware this is going to take the request of type request uh return type for now let's give it an any request type um so first of all let's say that I'm passing a beer token from the client and the you know the be token comes in uh in the key named authorization and uh then the value consists of two strings with the space beerer space and the actual token okay if I show you in the post man uh get users Au and this beer token this is already added currently but uh uh let's remove it uh we we can actually we need to add beerer space and then the actual token U I've I've created a separate video on the advanced uh technical concepts of Postman in my channel that includes the dynamically creating these token dynamically creating the environment M variables uh whenever we hit any kind of API so that is a very important video if you want to learn everything about Postman pretty much everything not uh the 100% thing but uh most of the things will be cleared from that video you can search uh Postman tutorial series on my channel um now let's come back and here I'm going to get it get the token and in order to get the token I can get it request. headers doget and it will be get authorization question mark If authorization exists then I'm going to split it with the space because beer space and then I'm going to get the second value all right so once that is done uh I'm going to Simply return is valid because this is what I'm going to be received in the middle be and I'm going to create a new function validate token I can directly write my code here but this is more convenient and understood um like this so above this I'm going to create this function so con validate token equals to token string and like this okay um it will have this colum this is passing the token to it uh argument string is not assignable uh to it and U yeah we can we can actually fix it once I write code so here what we can do is we need to actually write the valid token equals to token. length for now I'm not going to verify the actual token format if it is true or not if it is uh meeting the requirements or not I'm just checking if the token have length then it is this token is good we can authenticate user but you need to add your own logic um and check if the token is exists token have length and this is the correct token okay uh currently if token have length this will become true uh now I can write if token does not exist or if valid token does is not true okay uh then I'm simply going to return false otherwise I'm simply going to validate my token all right um so uh it's giving me an error there has to be an if condition all right so this token uh I can give it to any because sometimes this is not U so I'm going to use this o middleware in my main middleware file this is the predefined file uh so let's uh add first of all I'm going to add export default function middleware this is the built-in function which needs to be added request request and then the middleware all right first of all I'm simply going to return next response coming from the next server do nextt this is going to validate our apis uh now I'm going to add export const config equals to this and now I'm going to add the matcher matcher is going to be/ API slash any path okay static like this all right now if I go over here let's try to get all the users still I will be able to fetch all the users okay uh because I've not added any conditions so this middleware is actually applied to this configuration which I have added here now let's try to fetch that o middleware so I'm going to write const o result equals to Au middleware request okay uh Au metalware needs to be imported from the O metal Wares and if not Au result this is going to be is valid property which is coming from that file okay then I'm simply going to return an error message unauthorized okay so now let's verify I'm going to send it's returning HTML let's go um middleware this one U actually if we don't send the token then this length is going to give us some issues so I'm not going to use it uh you can validate it yourself based upon your condition I'm simply going to validate it to true for now okay so now I'm going to uh send it and now you can see that unauthorized the reason it's giving us unauthorized uh because this part actually got through so this token does not exists and because this authorization have does not have a second value token does not exist and this got true and that's why it returned false when it returned false then this is valid have become FAL true uh not true equals to like um the whole condition becomes true and this is what is going to get returned okay this is not uh something which is affecting here all right now if I go over here I add the BR token beor equals to any value okay because we are not checking the validation of this I'm going to send it now you can see that I am authenticated now every client site needs to pass some kind of be token to get access to all the apis if I want to get the notes let's send it's saying unauthorized again here I need to pass the beerer token uh it will be automatically populated because of the first request and I can send this out now I am authorized uh this is where you need to validate your token correctly I'm just showing you the way how things are done all right uh another thing quickly we we we need to organize our folder we can create multiple folders and uh move the requested and required request within the it specific folder just like I've done it previously above all right one last thing I would like to explain you is is adding multiple middle wees so middleware means that whenever any API request gets hit um that middleware gets executed before going to the API request and this is what happening over here as well I want to create another middleware and both of these middleware will be executed before any API requests that uh we trigger from the client side so I'm going to create another file inside this apis so let's add the logging middle there okay so what it's going to do is going to log up the method and the URL for the API which is getting triggered only for nodes API not for all the apis all right so this is going to have an export function logging middleware request of type request like this and simply going to return us an object let's say response request. method plus request. URL all right and we need to add a space here as well um this is going to give us U the method which can be the get put post whatever it is and this is the URL this is not going to work as it is now we need to use it in the middleware file now uh so let's come back here and uh Above This o middleware we need to log this out so if request we need to check uh the route path okay if then we are going to use this middleware so request. url. includes SL API SL noes like this okay if it is uh the notes request uh which is getting triggered then we can write the const log result equals to logging middleware request okay and then this is going to be the console log request and then we need to log the result log result and we have the response which is coming from that logging middleware over here so let's keep watching this terminal because on the server side uh we have the logged output in the terminal on the server side it will not be logged on the browser browser is only for the client side okay so let's come back to here first of all let's get the users it has fetched the users in the terminal it does not show this message the logging middleware because we have checked that only this API notes request needs to be triggered now let's get all the notes yes you can see in the terminal now you can see that the request the method type and the complete URL for the API is being shown which is perfectly fine this is what we wanted to do and using this if we if you need to detect um that any API route does not exist within this API folder you can check it again in this middleware file you can create an array of all the routes which you have created in this API folder and then you can check if the URL uh request includes uh any value from that array it means that it exists in your project in the API otherwise you can return an error message that not found this API route does not found all right uh this is some kind of idea which I've given you I'm sure there will be uh there is a better way um I've shown this thing in my previous videos as well where I have created the blog application e-commerce apps and you can check my previous videos so for now I hope that you have got an idea how you can build your rest apis in nextjs Frameworks along with the front end if you have learned something new do subscribe my channel like my video and comment below if you have any question thank you so much for watching my videos guys I'll be creating more videos in nextjs and also other Technologies as well like GitHub angular uh vue.js and the backend stuff like the node Express mongodb and also uh some devops thing like the AWS Docker cicd uh engine X um and these kinds of topics all right guys see you in the next video thank you so much for watching
Info
Channel: Programming with Umair
Views: 3,106
Rating: undefined out of 5
Keywords: build rest apis in next.js 14, next.js 14 api routes, next.js 14 tutorial, Next.js 14 middleware, protect routes in next.js 14, multiple middlewares in next.js 14, connect mongodb in next.js 14, mongoose modal in next.js 14, full stack app in next.js 14, build project in next.js 14, Build e commerce project in next.js 14, next.js vs react.js, Learn next.js 14
Id: -j7qvs3zKqM
Channel Id: undefined
Length: 87min 41sec (5261 seconds)
Published: Mon Jan 29 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.