NestJS Crash Course - Build a Complete Backend API

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody and welcome back to my channel i am super super excited to present to you my nest js course i've been working at this for quite a while now sjs is a terrific node.js framework that i am utilizing at work and i've learned so much about and i want to share that knowledge with you so i actually went ahead and i created a 10 hour udemy course with two projects the first project i'm going to present here on youtube for you guys but the second project is going to be exclusively on udemy i'm going to introduce both projects the first project is going to be for understanding the fundamentals of nest we're still going to learn quite a bit but then the other project is going to be for more advanced learning and really you want to develop your nest skills to become an expert i'll have a link in the description below with a discount if you are interested i hope you guys enjoy welcome to my nest js course i am super super excited to have you here and i'm sure you are going to be learning quite a lot an sjs is something that i have extensive experience with i actually use it all the time at my current job and i have grown and learned so much about it and i'm excited to share that with you so the first thing that i want to do is quickly introduce exactly what nest js is and then i'm going to introduce the projects that we are going to be building so the best thing to utilize in order to understand what a framework is is to go to the website so over here i am inside of the nest js.com website and the snippet that we have here pretty much describes exactly what nest js is a progressive node.js framework for building efficient reliable and scalable server side applications so let's actually begin with this part right over here so the first part is it's a node framework so it's a framework that is built on top of node over here it says it's progressive so a lot of node frameworks don't come with some of the things that we actually need to build an application with however nest js comes with a lot of different things right off the bat and we actually don't even have to introduce third part third-party libraries in order to do it also it has a great file folder structure file and folder structure that we can utilize and so that's why it is progressive now this application or this framework what it allows us to do is build scalable server-side applications so what is a server-side application well it is an application that is going to serve us information service data service a web page etc so we have to hit a specific endpoint and it is going to return data to us that is exactly what a server side application is now an api is a server-side application and that is the most common use case with nest js an api so that's exactly what we are going to be building in this course we're going to be utilizing sjs to build a rest api and if you're unfamiliar with the rest api do not worry i'll have an explanatory video about that so let's quickly go ahead and actually introduce exactly what we are going to be building so i'm gonna go over here i'm going to go to present mode and the first thing that we're going to be building is an expense application now this is going to be an api and this is going to allow us to learn the basics of nest js we're going to learn things about controllers about services about dtos interceptors modules as well as pipes so these are different entities inside of nestgs and if this doesn't make any sense to you that's okay but these are the fundamental blocks of nestgs and we're going to learn all about them inside of this expense app now once we complete this expense app we are going to move on to a realtor app this is going to mock one of the typical realtor websites like zillow.com or realtor.com of course it's gonna only mock the api side of it not the web side of it and over here we're gonna be building a more production ready application so we're going to have orm integration if you're unfamiliar with what that is well it's just a way that we can connect to a database and we will be connecting to a real postgres database that is going to be hosted in the cloud we're also going to talk about authentication as well as authorization we're also going to be talking about interceptors as well in more detail we're going to be talking about another entity called guards and another thing that is extremely important and is not taught is testing we're gonna learn exactly how we can test our nest api so i'm super super excited to have you here this is what we're gonna be building and i hope you guys enjoy in this video what we're gonna do is quickly explain exactly what a rest api is now in order to understand what a rest pi is we first need to understand the server client model in this video what we're going to do is quickly explain exactly what a rest api is now in order to understand what a rest api is you need to understand the web server model so what i'm going to do is i'm actually going to go to this website right over here realtor.ca and i'm going to start viewing some homes now right here you can see i'm getting a bunch of different home listings now let's actually take a look at these cards what are these cards well if you think about them from a software standpoint it's data so these cards are data so we have data about the home price we have data about the home address also the number of bedrooms number of bathrooms the realtor associated with them etc now this website how is it going to get this data well what it needs to do is make a request to a server and then the server can fetch that data from the database and then it's going to send that data back and we can actually look at this inside of this website itself by opening our google chrome inspection tools and going to the network tab i'm going to go ahead and just do a quick refresh and you can see all of the different calls that are being made and one of these calls is going to be to the api that is responsible for fetching this data so the fetching process isn't going to be in the website itself instead what we're going to do is we're going to have that business logic in the server so let's actually take a look at a diagram so over here we have our client which is again this website right over here and it needs this house data so what it's going to do is make a request to the server that is hosted somewhere else and is not accessible by anybody but this client saying that hey i want well data about houses so over here the server is going to process that request it's going to do a bunch of business logic it's going to interact with the database get those homes and then it's gonna send that data as a response to the client the client can then go ahead and populate that data and so it can you know be something like this all right so that's pretty much all that it is now you might be wondering exactly what is this request well inside of our server we can have multiple different endpoints and each endpoint can have a particular verb so for over here for example we can have a slash endpoint and this is responsible for getting all of our homes we're going to assign it with the verb get like so and this means we're going to make a get request to slash home and this endpoint is going to be responsible for while getting our homes and so our client if it needs to get all the homes is going to make this request you can also make another request to another endpoint if you want to get just one specific home this is going to be slash home slash the id of the home if we want to create a home we could also make a request to slash home but this time we're going to change the verb to post so typically if you want to create something the verb is post if you want to get something the verb is get we can also do the same thing for updating home with a put verb as well as deleting a home with a delete verb so what we can do is the client can access any particular endpoint and make that request in order to perform a certain action and so that is what we're going to be building inside of our nest application we are going to be building the server side and then the client can go ahead and just make requests and get responses in this video we're going to quickly discuss all of the different things that we need inside of our local machine to get started with nest js and thankfully there's actually not a lot that we need the first thing that we need is a code editor i highly suggest visual studio code so if you need a code editor go ahead and download it now feel free to use whatever code editor you want i will however be using visual studio code now because nest js is a node.js framework we need to have nodejs on our local machine so go ahead and install it if you don't it's just on nodejs.org download and download it for whatever operating system that you are utilizing i am utilizing mac so i would click on mac now i i already installed this so i'm not gonna install it again and the installation process is actually really easy so there's really no need to demo it now once everything is installed what you can actually do is open up your terminal let's go ahead and clean that so you can open up a terminal and you can very simply execute node v and if you get a version that means you have successfully installed a node on your local machine however if you're getting an error such as node command unknown that means you have to do some sort of troubleshooting because you didn't install it correctly and that is honestly all it is that you need to get started with this course one last thing that i want to discuss is that all of my code is going to be located inside of my github repo so if you ever need to refer to it go ahead go to the github repo you can either download it or clone it if you know get and you can just go ahead and utilize that if you are ever stuck so that's pretty much all it is that you need and let's actually get started with the first project all right my good friends i think now is a very good time to introduce our very first project now this is going to be an expense application and we're going to be building the api side of this expense app now what is this expense app going to do well we can utilize this application to add any source of income as well as any source of expenses and what it will do is going to save those income reports as well as those expense reports in the database so we can later take a look at them so again for example let's say i have a salary and my salary pays me one thousand dollars i can add that as a report inside of this application saying that this is an income report maybe i spent two hundred dollars on food i can add that as a report and then that will be an expense report and later on of course what i can do is i can compare and contrast my income versus my expenses using this application so let's just quick take a quick look at exactly what are the endpoints that we are going to be implementing in this app so the first five end points are going to be relating to incomes so over here we have slash report slash income and this is going to be a get request and then essentially what this endpoint is going to do is it's going to give us an array of all of our income reports over here we have another get request but this is going to be slash report slash income slash income i d so over here what this is going to do is just get us that one income report so it's just going to get us that one object rather than that array and then over here we have a post request to slash report slash income this will allow us to create an income report and then over here a put request to slash report slash income id and this of course is going to be a dynamic id and we'll talk about that later but this is going to allow us to update an income report and then over here we have this endpoint for deleting an income report so i hope this makes sense to you this is just basic rest principles now also we're going to have to deal with expenses so we're going to have endpoints that are very very identical like pretty much the same thing except instead of slash income it's going to be slash expense so this is to get all of our expenses to get to one expense this over here is to create an expense this over here is to update an expense and this one lastly is to delete an expense so i'm super super excited to do this even though it's a very very simplistic application and kind of a basic crud app there's a lot of different things that we are going to be learning in this project and they're really the fundamentals of nest and i wouldn't i wouldn't be surprised if there's going to be some things that are relatively complicated to understand because there's some things that we're going to be doing here that are going to be fundamental to the next project which has a lot of complexity and a lot of advanced nest features so stay tuned and i guess we'll get started on this one now that we talked about exactly what we are going to be building let's go ahead and create a new nest application to build that expense api now in order to do this what we first need to do is install the nest cli on our local machine and what the cli is is a command line interface that is going to give us a bunch of different commands that we can execute that are going to help us build our nest application so for example once we install the cli what we can do is we can build a boilerplate nest app with all of the dependencies that are needed already installed and nest is built with multiple entities like modules controllers services etc now we'll talk about that in great great detail but if we ever want to create any one of these entities we can use the cli to create it for us so it's very very recommended and very helpful to have the cli in utilizing this wonderful tool so let's go ahead and install the cli globally on our machine i'm over here on the nest js documentation docs.nestjs.com cli slash overview and it says here that in order to install the cli what we need to do is execute this command in our terminal so let's go ahead and copy this command and what i'm going to do is i'm going to open up my terminal and i'm going to zoom in quite a bit let's just zoom in zoom in zoom in zoom in and i'm going to paste this command and this command over here is going to be mpm install g meaning globally at nsjs cli now if you execute this and you have some permission errors what you can do is prepend sudo enter your computer password and then you should be able to install it correctly now this is going to take some time to globally install so i actually already did this but that is the command that you need to execute in order to install it now in order to check that you installed it correctly what i recommend doing is closing up the terminal and then opening up a new instance of that terminal so let's go ahead and open up a very new instance and then execute the command nest dash v and what this is going to do is going to give us the version of nest that you have installed on your machine if you get any virgin that means you have nest installed correctly and as you can see here i'm getting version 8.1.8 however if you get an error saying that this nest command is unknown something like this array over here command not found and then over here it says nest well that means you didn't install nest correctly and you're gonna have to do some troubleshooting however 99 of the time i do expect that the npm install dash g for global at nest cli that should work so now that we got that done what we need to do is we need to create a new nest project so in order to create a nest project let's go to the documentation let's scroll down over here and to create build and run a new nest project these are the steps that you have to take so over here what we're going to need to execute is nest and this is the cli and then new for new project and then my project name so over here what we can do is we can move into whatever directory you want this project to be created at let's say the desktop for me and then i'm going to say nest new and i'm going to give this application a name now i actually already created a brand new nest application that is called expense app not express app expense app i already created one just because this command does take some time so what i'm gonna do is i'm gonna call this two but i recommend you just calling it expense app now once you uh once you execute this command it's gonna ask you a few questions it's gonna ask you which package manager you want to use you should say npm for this now the installation process is going to take a few minutes so that's why i'm going to ctrl c and click out of it i already installed this so i'm just going to delete this additional folder that i got now what i can very simply do is go to vs code and open up my project so i actually already have it opened up but what you can do is you can open up vs code go to file open folder and then you can go to your desktop directory or whatever directory you created that nest application in click on it and then open and there we go you can see here that i have it open and this is what you should see so you should see a bunch of files and folders but the most important thing is this right over here the source this is where we're going to be doing 99 of our work so you should see it app dot app.controller you should see an app.module as well as an app.service so what i'm going to do is i want to actually start up this server i want to see if it actually works so let's go over to our package.json and let's look at this command right over here so it seems as though this is how we are going to run our nest application in development so start colon dev and that's actually the recommended uh recommended thing to run right over here so npm run start colon dev so what i'm going to do is i'm going to open up a new terminal and i am going to well run npm run and then i'm gonna do start colon dev so let's go ahead and run that and you can see now our application is up and running so now let's actually just test out that this app is running so you can see here and you don't have to understand what's going on but you can see here we have this method and it's calling this get hello method inside of the service file and it's returning hello world so what i'm going to do is i'm just going to go to localhost 3000 because this is where this application is running on localhost 3000 and we're going to see if well it's working and we get that hello world message and as you can see it is working so our api is up and running and it's working the way that we expect it to that's awesome now let's go ahead and start creating our app and creating those different endpoints in the last video what we did was we created our very first nest project and we got it running on localhost 3000 however what we want to do is implement these endpoints so in this video what we're going to do is learn exactly how we can implement different endpoints inside of nest now specifically for this very first lecture we're going to learn how we can implement this first end point now once we learn exactly how we can implement this one the other ones are going to be pretty much the same and a breeze now another thing i want to note is that this is supposed to return an array of objects each object is going to be an income report so whether it's salary youtube udemy etc now for this very first implementation because we're not storing any income reports we're just going to return a hard-coded empty array but remember this is the first version of the implementation afterwards we're gonna have a little bit of a database to interact with to actually get the real income reports that we want to store so again this is the very first implementation now how in the world are we going to create endpoints inside of nest well in sjs there's a bunch of different entities that we can utilize to do different things here is an example of five of the most common entities that we're going to be utilizing controllers modules services guards and data transfer objects now there are more entities inside of nest but these are the five most common now each one of these entities is going to do a different thing inside of our nest application and actually one of them is going to be responsible for creating well endpoints now which one is that well it is going to be the controller so the controller entity is responsible for creating endpoints inside of our nest application so let's actually go ahead and well create this very first endpoint right over here inside of a controller all right so let's go into our source directory and you can see in our source directory we have well a lot of these entities that i talked about we have the app.controller.ts we have the app.module.ts we have the app.service.ts we know what we want to do is we want to create a well new endpoint so what we're going to do to create this endpoint is move into the app.controller.ts and for this very first implementation what i am going to do is delete everything and we're going to work from scratch just so we can really learn what's going on with controllers later on we're gonna utilize whatever the next cli defaults for us but again for this very first implement implementation let's go ahead and delete everything inside of the app.controller.t file so i'm going to go ahead and save this now what we're going to do here is we want to create a new controller entity now every single entity inside of nest js is a class so everything is going to be a class a service a module a guard everything is a class so what we're going to do here is we're going to say class and then we're going to say controller we're going to give this class a name and we're going to have our curly braces so this right here is our class now right now nest has no idea what entity this is is it a module is it a controller is it a service all these different entities have different uh features and different abilities so what we need to do is we need to tell nest js that this is going to be a controller and should have the ability to create endpoints in order to do this we are going to utilize what is known as a decorator so over here we're going to import a decorator and if you don't know what that is do not worry so we're going to import some decorator that i'll talk about a little bit later we're going to import that from at nest js and then slash common so slash common and we are going to import something called controller you can see here that this is a class decorator so what we can do is we can grab this decorator and right above the class that we want it to be a controller we can say at and then controller and then invoke it like a function and so what this is going to do is give this class the ability to be a controller and that's really all it is that we have to do now inside of here what we can do is we can create different methods and these different methods are going to return whatever that endpoint is supposed to return now for example over here what we want to do is we want to return all of the income reports so i'm going to say here get all income reports so get all income reports and again what this method is going to do is return whatever this endpoint is supposed to return now for our very first implementation what we wanted to do is return an empty array so this method is going to return an empty array and this is actually going to be the http response that we get back so let's return right here now so this is all fine and dandy however what we need to do is we need to tell nest js that this is going to be a get request because again it could be a get it could be a post it could be a delete could be whatever so we need to tell it specifically that this is going to be a get request so what we can do here is inside of nest common we can import another decorator known as this get decorator and we don't put this get decorator on top of the class instead we put it on top of the method so over here what we can do is we can grab this decorator and right on top of the method we can say that this method is going to be responsible for a get request so once we make a get request at a specific path it should call this method and return whatever this method is returning so an empty array and this is all it is that we have to do really that's pretty much it so now what we can do is we can go ahead and save this and the very last thing that we need to do is we need to export this class the reason why we need to export this class is because it's being used here in the app.module.ts this is another entity that we'll talk about a little bit later but you can see here that it's being used and it's put inside of this array where the property is controllers so we're going to go ahead and save this and now what we're going to do is we're going to go back to localhost 3000 and we're just going to do a quick refresh and once we get the refresh you can see that we get an empty array so inside of our browser we're always making get requests and so we're making this get request right over here so this is the get request that we're making to localhost 3000 and then slash we have really no path and so what's happening here is okay because this is a get request it sees okay well this is the get decorator we need to call this method and this method over here is returning an empty array now if we were to return an object for instance let's comment that out and let's do a refresh you can see that we get an object so congrats we actually implemented our very first endpoint at this point we are getting really close however we're not quite there yet in order to return this array and call this method what we have to do is call this endpoint so http colon host colon 3000 however this isn't what we wanted instead what we wanted to do is hit the endpoint slash report slash income so we should have something like this instead and calling this endpoint should call this method and return an array however let's go ahead and give this a call and let's put it in our browser and let's see what happens so once we actually call it we get a object and this actually is a error object so you can see here we have a status code of 404 and if you know your http codes this is a not found code and very simply what it's stating here is this this endpoint right here is not found inside of our nest application we did not define it anywhere and that makes sense because well we didn't define it anywhere right now we are in the app.controller.ts and this is actually the root file so it's going to have just the bare bone simple slash so it's just going to be whatever this api is called and the path is just going to be a slash which basically means it's empty again what we want is slash report slash income now how can we accomplish this well we can actually accomplish this very easily utilizing either the controller decorator or this get decorator very simply all we have to do and let me just quickly explain this is what we have right now all we have to do is grab what we want to append to this api path so inside of the controller i'm going to say i want to append slash report income and now what's going to happen is it's going to look something like this so it's going to be our api and then plus this path and so now if you were to save this and go to refresh this you can see now we have our empty array this is really good now we can actually do the exact same thing inside of our get so what i'm going to do is i'm going to put it inside the get and this is actually going to result in the exact same thing so what i'm going to do is i'm going to go ahead and save that and refresh and you can see that everything is working fine if i went to localhost 3000 on its own so i'm just going to copy that and paste that in you can see now we're getting an error saying that hey this path doesn't exist which makes sense okay so this is all fine and dandy but when do i put this in the get and when do i put it in the controller is there a difference well there actually is quite a big difference so inside of our controller we might have multiple methods we might have multiple route handlers for example what i'm going to do is i'm going to go here i'm going to grab another get request i'm going to call this get all income reports 2 and this is just going to return an object so this is going to return an empty object and what i'm going to do is over here i'm going to make this empty i'm going to make this empty as well and then for this i'm going to say let's say let's just add something in here let's say report or you know what let's say let's add something else let's say hello this is very generic so what do you think will happen here okay so over here what's happening is well we're appending nothing so if we hit localhost 3000 we should get this array right over here so let's go over here let's paste that in and that's exactly what we get we get this array now over here what we're doing is we're appending hello so hello so it should be something like this so let me go ahead and copy that so if we hit this endpoint we should return an object rather than an array so let's go here let's return this and as you can see we're returning an object now what i want to do is inside of the controller i am going to add hi so i i hope you have the gist of what's gonna happen here so i'm gonna go ahead and save this and i'm gonna try to hit this end point so remember this endpoint before was localhost 3000 plus nothing so very simply just localhost 3000. so what i'm going to do is i'm going to go here paste that in and now we're getting an error saying that hey this route is not found let's actually go ahead and try this endpoint now so what i'm going to do is i'm going to go localhost 3000 slash hello and i'm going to go ahead and paste that in and well i'm also getting an error here so what's happening here is that whatever is the in the controller is going to be appended for every single route inside of the controller class so what is really happening what's really is happening here is we have the api over here and then it's going to be plus whatever is in the controller and then plus whatever is in the method decorators decorators and and this i mean the decorators as well decorators so that's getting a little messy but i hope you know what i mean here so what's happening right now if we want to hit this endpoint it's going to be localhost 3000 plus high and then plus nothing so really it's going to be localhost 3000 slash high and this should give us an empty array now if we want to hit this endpoint then it's going to be localhost 3000 plus high plus hello so like like so so it's going to be then slash hello like that so now if i were to paste that in you can see we get our object you kind of get the gist at this point if we have a certain path that we want applied in every single endpoint inside of our controller we're going to put it inside of well the controller decorator if we have a path that we want specifically to be appended for a certain endpoint and not other endpoints then we're going to put it inside of these method decorators right over here i hope that makes sense so let's actually look at what we have here so we have slash report slash income so this seems so slash report slash income is consistent across all of the endpoints now there are some other endpoints that have slash id but slash report slash income is consistent across all of the endpoints so what if we just put the slash report slash income inside of the controller and then these slash ids inside of the method decorators that actually need them so it's going to be the get the put and the delete and this is the actual right way to go so over here we're going to do slash report slash income now over here this actually could either be an income or an expense so we have to somehow make this dynamic but we'll talk about that a little bit later what i'm going to do now is i'm going to completely get rid of this and let's just save that for now we're probably going to get rid of this method later but let's save that for now and now what we're going to do is we're going to hit slash low close 3000 plus the controller and remember there's nothing inside of the get we can either leave this as an empty string where we can just completely remove the string itself and so the path is going to look like so so this is how the path is going to look like and now if you were to paste it here you can see we have our empty array okay so i hope that is clear now we're going to move on to the next video in this video what we're going to do is focus in on this endpoint right over here so when this endpoint again what we're supposed to do is just return a specific income report based on that incomes report id that's really all it is that we have to do so the path should look something like this so slash income or slash report slash income and then slash whatever the id is now the id that we're gonna do is a uuid so it could look something like this right over here as you can see it could be anything now what this should do is return an object of that income report now this actually gives us a little bit of complication how in the world are we going to make this part over here dynamic right now it is hard coded so report slash income but over here we need it to be support slash income which is handled by the controller but then a dynamic id so how in the world are we going to accomplish this well this is very very easy let's actually go over here and let's rename this method this is the method that's going to give us the object and for now we'll just leave it as an empty object so over here we're going to call this we're going to call this get income report by id and then this is going to have the path of slash report slash income which is handled by the controller and then slash id so what i'm gonna do just for now is say slash id like so so let's actually just take this request and paste it in here so i'm going to paste that in there and you can see that this is giving us an error however if i changed this to slash id and that's what i'm going to do i'm going to change it to slash id copy it and paste it back in well that works and you might expect that to work now this is because this id is hard coded instead what we want to do is we want to say that this path over here can be dynamic and whatever that path name is we want to give it the variable id in order to do this all we have to do is say colon and then id now again this could be called whatever it is that we want but whatever this path is going to be so for example if this path is like this then the variable name is going to be this over here so in order to access this the variable of this will be equal to the path so of course we want this to make sense so we're going to call it id and therefore it's going to look something like this instead id is equal to this path so now if i went ahead and i made this request so let's go here and made this request you can see that we're getting an object and in fact i can make anything and i still get this object because we're still heading this end endpoint now you might be thinking well how in the world am i going to extract the id i'm going to need it eventually don't worry we'll talk about that later now there is one thing that i do want to discuss now that we've learned this right over here we have to understand that we actually both want income reports as well as expense reports so really what we need here is something like slash income when we want to hit the income but whenever we want to do something with an expense well we want to of course call the expense we want to call it like this so we actually don't want to hard code this value right over here we kind of want to make this dynamic well we can make it dynamic the same way we made this dynamic so instead of having a hard-coded income what we can do is we can do colon and we can call this report or report type maybe we can just call it type so slash report slash type whether it's income or expense so now what we can do is either hit the income or the expense so over here what we can do is let's go here so if we were to do slash report slash expense this still should hit this array right over here so i'm going to go here copy that and paste that in so you can see that this is working a okay now you might be thinking well this could result in some major complications what if somebody instead did something like slash report slash whatever like this and obviously what we want instead is slash report slash either income or expense we don't want this gibberish well what we can do very simply is inside of the method itself we can get this type we can check this type and if it's some sort of invalid type you can throw an error so we can do this manually ourselves however again at this point this is going to return an empty array later on we'll fix this all right this is terrific so we're getting really really close in the next video let's actually finish this off and create the post put and delete requests i highly encourage that you guys try to implement these endpoints these last three endpoints by yourself really there is nothing new here so we've actually talked about exactly how we would implement all of these now just as a quick hint over here instead of the get decorators we're going to need some other decorators to say that these methods are going to be responsible for either post put and delete requests so i'll give you guys five seconds to pause the video and implement it by yourself all right i hope you guys gave that a go let's begin with the post request so this is going to be to slash report slash income remember this is already handled by the controller so really inside of the post decorator we are not going to be having anything inside of it so over here let's go let's grab the post decorator so we have the post post if i can spell that right here the post decorator and i'm going to say act post and then over here we're going to say create and we're going to change the names a little bit instead of getting all income reports what we're going to call it is get all reports because this can either be an expense report or an income report so over here we're going to say get report by id and over here we're going to say create report so we're going to create this report and that's really all it is that we have to do for now let's just create a let's return to string saying created something very simple like that now over here let's do the same thing with the put as well as the delete over here let's grab our put verb our decorator we're going to say at put now over here you can see slash income or slash report income okay this is handled by our controller but we have this dynamic id so over here what we can do is slash our colon id and then over here we can say update report now the last one you guys probably get the trick over here let's also return something saying updated so for the delete let's grab the delete decorator we're going to say act delete and this we're going to have the colon id because we need to know exactly what report we want to delete we're going to say delete report and for now what we're going to do is we are going to well just return the string delete now these endpoints we actually can't hit them inside of our browser so these uh right over here we can hit them because they're get requests however these are post put and delete requests now in order to actually utilize them i i encourage you guys to utilize postman now in the introductory videos i showed you exactly everything that you needed to install one of them was postman so i hope you guys have that installed so what i'm gonna do is i'm gonna open up postman let's open that up it's taking it's sweet time i'm just gonna get rid of completely everything and i'm gonna go here and you you can see here that i've i use postman a lot for all of my different projects and what i'm gonna do is i'm gonna delete this expense because that's exactly what i was using before let's also delete this to do just to make it less cluttered maybe even the sub app you don't have to do this it's fine what i'm going to do is i'm going to click on this button right here let me zoom in click on this button and this is going to create a new collection for us so i'm going to rename this collection by right clicking and i'm going to call it expense app as you can see i already have an expense app so what i need to do is well delete the other expense app let's go ahead and do that now this right here is a folder and inside of this folder we can have multiple different requests so we can add a new request and let's actually add a get request so we we've been hitting which endpoint this endpoint thus far so let's go ahead and paste this request in that we've been hitting inside of the browser so we're going to say slash income like so so now what we can do is we can actually send this off and you can see that we get back this empty array so we can actually give this request a name so we can say here get all reports so get all reports and we can save that now let's actually give it a let's give the post request a try so we can say here create a report and we can say post for this and now what we can do here is call that exact same endpoint but this time it's a post request because i changed the verb here we can send this off and now you can see we get the string back created so i hope this makes sense you can of course do the same for the put as well as the delete so this should update a report let's say put let's give that a quick save let's grab this endpoint now remember this is going to be slash report slash income slash whatever id so let's just say one two three for now and as you can see here we get updated everything seems fine let's do the last one which is the delete so i'm going to say here delete and let's grab this and we're gonna go ahead and save that and now you can see delete okay everything seems like it's working just fine of course none of this is really functional we're just returning empty arrays empty objects and random strings we obviously want to do things but at this point we really implemented all of our endpoints so we've pretty much learned really all it is that we need to know about controllers controllers are classes that allow us to create different endpoints so this actually concludes this section in the next section what we're going to do is we're going to start making well this functional of course now that we have created all of the endpoints let's actually make these endpoints functional thus we want to make these endpoints do something rather than return a bunch of gibberish now in order to do this what we need to do is create a database where we can store all of our reports now for this very first project what we are going to do is utilize just a very simple local database we are not going to be utilizing a full-blown database like postgres or mongodb we're actually going to learn how to do that in the next project but for this project let's just use a local database so that we don't take the focus away from sjs so this is going to be a very easy implementation right in the source let's create a data dot ts file now notice here that i said ts and i actually didn't introduce this at the moment but nest js is almost 99 of the time written in typescript so what we're going to do here is we're going to be working with typescript and that's why every single extension is dot ts now i didn't mention this because i didn't want you guys to worry about typescript you need to know absolutely no typescript knowledge to take this course so that's why i didn't bother mentioning it but once we go over here and creating our data we're going to be doing a lot of typing and typing is going to involve well a lot of typescript knowledge so we're going to learn a little bit of typescript when we create this database now in case you don't know what typescript is it's basically a way where we can type our variables so for example because we're using typescript what we can do is something like let name is equal to you know my name the string my name and as you can see here we're getting some sort of error let's just say my name the name the variable name is always kind of iffy but now what i can do here because we assigned it as let we can do my name is equal to um i don't know we can change it to jess if we wanted to we can then change my name to uh let's change it to jaw so we can change it to whatever it is that we want however we cannot and we can do this in javascript but with typescript we can't do something like this assign my name to 44. the reason for this is if we hover over it you can see here that because we declared my name and we gave it the value of lathe that is it that is a string what ends up happening is that typescript says hey this is of type string and we cannot change it to something that is not a string which is a number if we hover over this error you can see here that it says type number is not assignable to type string so this is actually really really cool it gives us a lot of type casting and it allows us to catch a lot of these errors inside of development so that's really the gist of what you need to know everything is very strictly typed in typescript so what i'm going to do here is i am going to create a constant called data and this constant is going to be an object and this object is going to contain a property called report and this is going to be an empty array initially now in here what we are going to do is well pass in the reports so inside of this object we're gonna have a report and each report is gonna have an id it's gonna have a source so you know the the source of that report so if it's an income report is it your salary is it some other sources is it your e-commerce business etc if it's an expense it might be food it might be equipment etc something like that we're also going to have an amount so how much income or how much expense we're also going to have a created ad so when this was created at and also we're going to have an updated at and then we're also going to have a type so whether this is a income or an expense now in typescript what we should do is actually give this array a type right now when we hover over it you can see that this data has a type that is an object and inside of that object we have a property called report and this report is the the value of it is going to be an array but you can see here it's going to be an array of anything so what we can do here is we can do data dot report dot push and we can push in a string we can push in a number if we want to we can push in a boolean so a boolean or we should probably actually pass in a real boolean like true but what we really want to push in is something like this again we want to push in an id that is going to be a string so i don't know some sort of uuid we want to pass in a source so we can say salary we also want to pass in a an amount so let's say 7 500. and then we also want to pass in a created at and this is going to be a date so we can say new date something like that and over here we're going to create also pass in an updated act let's just also say new date for this and lastly we're going to pass in a report or a type a report type so we just say type for this and this can either be expense or income so what we want to very simply do is be able to push an object like this however if we try to push this gibberish it should throw an error so what we need to do is specifically tell typescript exactly what is inside of this array now one one way we can do this is we can actually grab this object and we can pass it inside of this array now what happens you can see here we're getting a bunch of errors because typescript now is able to infer that the uh that the report is going to contain an object an array of these objects over here id string source string amount string etc however of course what we don't want to do is we don't want to pass in something initially we initially want it to be empty so how is it that we can type it with leaving this empty well we can actually do this very easily in order to type objects what we can do is utilize an interface so an interface is a way that we can type objects so we're going to call this interface data and we're going to do curly brackets and then in here we're going to supply it with the type so this is going to be an object that is going to contain a report property and this report property is also going to be an array of objects so array of objects now this object is going to contain an id that is a string it's going to contain a source that is a string and amount this is going to be a number a created act that is going to be a date also an updated act that's also going to be a date so let's do date here and then we also have a type so i type that is going to be for now let's leave it as a string so this is really all we have to do and in order to actually get this type what we can do here is right after the data a variable we can do colon data and now we assign this to this data type and now you can see we're getting errors here however we're not getting any errors here this is terrific that's exactly what we want so now we can get rid of that and really quite frankly we can get rid of this now one thing that i do want to note is that this type right over here really can either be an expense or an income it cannot be any other string so maybe we can actually type this even better so because right now what we can do is we can get rid of this expense and we can say bananas and this works really what we want to do is have this string either be an expense or an income so right here instead of saying that this is going to be a generic string what we can do here is we can say that this is either going to be income the string income or the string expense and so now you can see we're getting an error here saying that hey this is gonna be of type either uh income or expense so banana is not uh assignable to type income or expense now another way we can actually do this is utilizing an enum so an enum really is effectively doing the same exact thing but it's a lot better because we can actually export the enum and start utilizing it elsewhere in our code so over here what we can say is we can say enum and we can say report type and then in here we can say income and then we can say here that this is equal to income and then over here we can also say expense we can say that that is equal to expense you can have a comma here now over here what we can say is that this is of type enum now over here we can say you know we can't say income but we say instead is report type dot expense or income so this ensures that it's either going to be an expense or an income so that's just a little bit of typing now the last thing that we absolutely need to do is just export this because we're going to want to use it in different files but that's pretty much it and hopefully this little lesson taught you quite a bit of typescript because this is really all you have to know if you understand this you pretty much understand all you have to know with typescript inside of nest js let us begin by implementing the real logic for this endpoint right over here as a quick reminder this is going to get all of our reports now the first thing that we actually need to determine is what type of reports do we want to get back do we want to get back well income reports or expense reports how do we determine that well we determine that by the dynamic type we set over here remember this is going to be either report slash income or report slash expense so we need to determine exactly well do we want an expense or a income and of course we're going to do that by getting this type somehow inside of this method now how are we going to get this dynamic type in this method well we do that with param decorators so param decorators are decorators that are going to allow us to extract certain things from the request now in this case we want to extract this path parameter right over here so what we're going to do is we're going to get this param decorator and now in here we're going to do add param so this is in the parameter of the method we're going to do at param saying that we want to extract the parameter and we have to specify exactly what parameter we want to extract in this case i'm going to say type so over here as you can see we're going to get the type now what we want to do is we want to assign this parameter to a specific name let's also call it type and we're also going to say that this is of type string so really simple stuff so what we're saying here is we want to extract whatever this is we're going to assign it to a variable called type we can call this whatever it doesn't have to be the exact same name and we're going to say that this is of type string let's actually just console.log the type just to see what's going on here so i'm going to open up my terminal let's close this off as you can see here my terminal is up and running what i'm going to do is i am going to close here and i'm going to go to uh postman and inside of postman i'm going to make a request to get all of the report all the reports and what i'm going to do is i'm going to do it slash income so now when i make this request you can see here that we get income if i were to change this to expense you can see that we get the expense now if i were to change this to complete gibberish let's change that to gibberish you can see we get gibberish now obviously this is not what we want to either want to get income or expense but for now we're gonna trust the user that they provide us with income more expense later on we're gonna learn how we can perform this type of validation okay so right now again we're gonna assume that it's either income or expense so let's actually change it to income so what we're going to do is once we determine what the type is we need to actually filter for that specific type so what we can very simply do here is import that data so let's go ahead and import the data we're going to say from we're going to move or we're going to go to the source directory then we're going to go to data and inside of the data let's actually just put some uh dummy uh uh reports for now so let's go over here we're gonna have an object let's have a string of uuid one let's also have a source of let's have a source of salary let's also have an amount so we're going to have an amount of 7 500. we're also going to have a created act of new date an updated act of new date and let's also have a type now you can see that it's all red because we still need to pass in some things like the type and this is going to be an enum type so we're going to say report type dot income really simple stuff now over here we're getting an error so let's actually just go ahead and move this to the very top just so that we don't get this error anymore so now what we're going to do is let's just have some more income types so let's say youtube pays me 2200 and these are just made up numbers by the way and then over here this is gonna have a uuid of two and then let's say this one you id of three this one food let's say 500 and this is going to be an expense so of course if we want all of the incomes then what we're going to do is we're going to supply it with income if you want all of the expenses we're going to supply the type with expense so what do we want to do now well now what we want to do is we want to filter so very simply all we really have to do is say data dot report dot filter so you want to perform this filter we're going to say here we're going to get all of the reports and what we're going to do is we're going to say if type triple equals and we're going to say if a triple equals to um income then what we want to do is return so what we want to do is we want to return all of the reports where that enum value is uh report type dot income so actually what we can do here is before the return we can actually assign report type to be equal to and then if the report type so if the report if the type itself is equal to income what we can very simply do is import that enum from the data so let's go here and it's actually export that so we're going to say export and we can say here report type you can see that it auto imported is income and then else we're going to say that it's going to be [Music] a report type of expense so very simply what we're doing here is we're checking the type in the parameter if it's income we're going to assign this variable report type to the enum and if it's not then we know it's going to be expense so we're going to assign it to expense very simple stuff we're doing here and now what we can very simply do is just return all of the reports where their type is equal to the report type that we assigned okay i hope that makes sense now what we can do is just test this out so let's go over here to uh to postman and let's make this request so we should get two report types both of them income and it seems like we're getting them as you can see here we got them how cool is that now if i went ahead and i changed this to expense now you can see here that well we got an expense cool and that's pretty much all it is that we need to do very very simple stuff so now what we want to do is move on to this one right here this one's a little bit more complicated but you know we did this one so i believe we can also do this one let's actually do that in the next video this end point over here is going to be slightly more difficult the reason for this is because we need to extract the type whether it's income or expense and then we need to extract the id so we need to extract both of these path parameters so let's actually just begin by extracting the type we've already done this before what we're going to say is act param we're going to go ahead and extract the type so let's put that in a string we're going to assign it to a variable call type and then what we're gonna do is we're gonna give it the uh type of string and now what we need to do is get the id and believe it or not surprisingly it's gonna be the exact same process it's going to be another parameter so let's have a comma we're going to say param we're going to extract the id this time remember the id right here we're going to give it the value of id and this is also going to be a string remember it's going to be a uuid we're going to learn later on exactly how we can actually validate that this is a real uuid so that we don't waste our time with our request if it's not a uuid because then it won't match any of our records anyways so now we are going to get the type as well as the id just as a quick proof let's go ahead and console.log we're going to console them in an object let's get rid of this we're going to say type and the id very simple stuff let's open up our console and let's actually create a new request so we're going to say add request let's go ahead and copy this and then over here we're going to do slash expense slash uuid one let's go off and send this request we get back an empty object and you can see here that we get back expense uuid one so it's working the way that we expect it to how terrific is that so now what do we want to do well let's first determine what uh what type what report type we have over here as you can see we're going to do this and then what we're going to do is we are first going to filter by report type and then we are going to try to find the report with that id the reason for this is because what if somebody provides us with a report type of expense but a uuid that is related to an income so in that case what we want to do is we want to just return nothing we want to say hey nothing was found sorry however if they went ahead and changed that report type to income then we want to return an actual object so let's just make sure that we're returning the correct thing so over here what we're gonna do is a very similar filter to what we did over here so we're gonna do data dot report dot filter then we're going to say report so we're going to say report report.type is equal to report type so that is the filter and that's going to return an array of filtered objects and then on this array what we're going to do is a dot find so let's do a dot find here and let's go over here let's do a report and then what we're going to do here is we're going to say report dot id triple equals the id that we have in our param so id and that's really all it is that we need to do you can get rid of this extra uh return useless return at this point so let's just let's just give this a quick test right now we can look at the things that we have let's use income and ui df1 let's see what we get so let's go here income and uuidf1 and you can see barely you can see here that this is what we get we get the correct thing now if i were to change this to an expense with a uuid of one remember this corresponds to an income we should get null which is nothing no however if i were to change this to three now you can see we get a we get that that was the purpose of the filter so that's pretty much it uh it was a little bit different in that now we're utilizing two params but hopefully it wasn't too different from what we did over here okay so now let's actually move on to this and this one's going to be actually significantly different for this endpoint we are going to be creating a new report now the reason why this is significantly different is this time we are going to be requesting data from the user i guess in these endpoints we are also requesting data from the user in the path parameters but this time we are going to ask for the data inside of the request body so what we need to do is somehow extract all of the data from that body and validate that it is the correct data now the validation steps will do a little bit later but for now we're going to learn exactly how we can extract data from a request body just as an example what we're going to do here is in our post request once we make it inside of the request body we're going to go over here we're going to go to raw and then to json and we're going to pass in some data now the data that we're going to pass in is going to be the source and the amount the created at as well as the updated at we can generate that ourselves and the type is going to be coming from the uh path parameter so let's go over here and it's going to look something like this source let's say udemy and then we're going to say amount is going to be let's say 5000. so this is what we have over here and we need to somehow extract this in order to create our report so let's go here and let's send off this request and we should get in the body the string created but what we want to do here is we want to figure out exactly and let's get rid of this guy in the middle by the way it's getting kind of annoying what you want to do inside of the controller is get that body now in order to do that we're going to use another decorator that we're going to put inside of the parameter so it's another parameter decorator and it's going to be the body and as you can imagine what this is going to do is extract the body from the incoming request so we're going to say body and then we're going to invoke it and then what we're going to do is we're going to assign it to a specific variable and let's go ahead and give it a type now this is going to be an object where we have an amount that is going to be a number and also we're going to have a source that is going to be a string now later on we're going to change this to something a little bit better but for now we'll leave it as is let's go ahead and console.log the body so i'm going to put it inside of an object and let's open up our terminal let's go here and let's go ahead and make this request and we should get an object where we have body and then we have this object over here as you can see we're able to extract everything this is really great so now all it is that we need to do is just create a new report so over here let's just say new reports and then this is going to be equal to an object what we need is an id and this is going to be a string now remember this is going to be a uuid so what we can very simply do here is actually install a library called uuid so we're going to install the library itself as well as its associated types because we're using typescript now what we can do here is import that so uuid has a bunch of different algorithms that uh we can utilize in order to create a uuid it has v1 v2 v3 v4 and each algorithm it creates a uuid in a different way the most recommended use case is v4 so what we can do is we can utilize v4 and i want to actually rename this to uuid so in typescript we can just say as uuid so essentially what we're doing here is we're taking this v4 variable and we're assigning it to uuid now what we can do here is very simply just invoke uuid and what this should do is just generate a random string for us so that's the very first thing the next thing that we need is the source so we can say source and we can get that from the body dot source so the body dot source however i think instead of just having the body like this let's just go ahead and de-structure out the amount as well as the source so it can look like this and we can even actually even simplify that more to this so we can say source we can also say amount we can say created at that's going to be new date let's also say updated at that's going to also be new date and then the last thing we need is the type and the type we're going to have to extract that from the parameters so let's go ahead and extract that so we're going to say at param we're going to say type and this is going to be the variable type we're going to give it a string now over here what we can just again very simply do is actually just utilize this part right here so we can paste that in so if the type is triple equals to income we'll make it this enum else will make it this enum okay so that is going to generate it and again this is pretty much assuming that the type is always either income or expense so once we have created it what we can very simply do now is we need to push it into our database so we can say data dot report and then over here we can say dot push and we can push our new reports now if we ever made any sort of mistake in here so for example maybe we said that the amount is equal to the source typescript is going to yell at us over here it's saying that amount string is uh you know not equal to what we defined in the data file so that's really good that's the real the whole purpose of typescript so we created we pushed it inside of our database and the last thing that we need to do is just return it let's go ahead and return the new report that we created so let's go to postman and let's send off this request seems like everything is a-okay you can see that something has been created very cool and it has this uuid so now if we try to make a get request to get all of them for example you can see here that we get the usual that we have we're actually actually getting all of the incomes let's get all of the expenses so we get this over here we get this and we also get our own really cool okay so we actually pretty much implemented all of the logic and really needed in order to understand how to implement these two these two should be relatively easy there's nothing that's going to be new from here so i highly encourage that you guys kind of accomplish this and try this out on your own i hope you guys gave that a go on your own i am going to assume that the put request is gonna be probably logistically the most complicated thing to do from a logic standpoint however there's nothing new in terms of nest that uh we need to do in order to well complete this request so in here what we need to actually extract is three different things we need to extract the type we also need to extract the id and then we also need to extract the body and the body is going to contain the updated the updated either the amount or the source now over here let's go ahead and extract these three params so we're going to say at param and we're going to say type so let's say type over here now we're going to say type and this is going to be a string we're also going to do at param and this is going to be of type uh id or not type id it's going to be a type string but we're going to extract the id and the last thing that we need to do is get the body so the body over here we're going to say at body we're going to destructure out there actually we're going to leave it like so so body and this is going to be of type the same type that we have right here now we're duplicating the types typically what i would do is create an interface but we're going to replace it anyway so might as well just leave it like that so the first thing that i want to do is i want to actually find the report itself so i want to find that report if that report actually exists then we want to continue with our logic if it doesn't exist then well we don't want to continue with our logic so let's actually copy some of the same code right over here so this is the code that we're going to copy let's copy all that and let's paste it right in there so what we're going to do here is we're going to do const and we're going to say report is equal to this so this is the report now if we don't find any report then what we're going to do is we're going to get null here so we're going to say if the report doesn't exist then let's just return later on we'll learn how to throw errors but for now we're just going to cut it early and return however if the report does exist then i want to find exactly where that exists inside of this array best way to do that is to determine the index of that report so let's go here and let's say report index and what we're going to do here is we're going to say data dot report and then we're going to say dot find index and we're going to do this on we're not going to do a filter because again we want to find the location we already found that the report exists and it is of the correct type over here now we need to find the location inside of this array and remember this array is going to have a mix up of both report types that are income and expense so we're going to say here find index and in here we're going to say the condition is going to be come on vs code where the condition is going to be report dot id is equal to and maybe we should change this to uh report to update report to update just so that uh just so we don't have a lot of this mixed up over here where the report.id is equal to the report to update dot id now once we find this index all we really have to do is perform the update so over here what we can say is data dot report of that index so of that report index is going to be equal to and then what we're going to do is we're going to assign it to an empty object however what we're going to do is we're going to grab everything inside of this object and we're going to destructure it out and then we're gonna grab everything inside of the body and then we're also gonna destructure it out now if you notice any potential problems with this solution well that's okay i'm gonna leave it there on purpose there are problems with it but later on we'll fix it do not worry however this is how we're gonna perform this update and now what we're gonna do is return that new updated that new updated report so let's go ahead and save that for now and let's actually just give this a quick go so what i'm going to do is i'm going to create this new report actually this is a get request let's go here let's create a new report and let's say by accident it's not five thousand it's actually uh four thousand so i wanna update the amount so what i'm going to do here is i am going to go to the update so the update and what i need to do first is grab the id of the report because that's the id that i want to update it as actually before i do that let's go here and let's view it so you can see here we have it and it has amount of 5000 so now let's go to update let's pass in this id in the body what we're gonna do is we are going to provide raw json and then in here we're gonna say source udemy now if we're only updating the uh amount then we probably don't want to use source we want we probably don't want to provide source and we actually don't really have to but let's just do it for now anyways we're going to say 4 000. so let's go ahead and send this request off you can see here that now we actually get this request over here and you can see that it is of 4 000. if however i decide to change the id to i don't know something else like six you can see we get nothing back so it seems like everything is fine now if i try to make a request to get all of them and scroll all the way down you can see that the update works a okay so this one was by far the most complicated one i hope uh i hope you guys got the gist of what's going on here uh in the next video let's complete the implementation with the delete the last thing that we need to do is figure out exactly how to delete a report so to do this of course what we need to do is extract out the param the id so let's go here and let's go ahead and do that and that's going to be of type string the first thing that we are going to need to do is find the index of the element that we want to delete so let's go here let's say reports index and that is going to be equal to data dot report dot find index and we're going to say report now we're going to say where the report dot id triple equals the id that we have in our parameter if the report index is equal to negative one so if if the report index is um not found what actually ends up happening is that it's equal to negative one so it's it's uh it's not going to be equal to null it's going to be equal to negative 1. so if we over here what we're going to say is if the report index equals to negative 1 which means we haven't found anything let's just return we're going to throw an error later but for now we're going to return now if we pass this if block that means there is something in there and what we want to do is we want to get rid of it so what we can do here is we can filter it out or we can actually use the splice method so what we can say here is data.report and then we can use dot splice and then what we can do here is provide the index where we want to start the splice and that's going to be this index and then we need to state how many um how many elements do we want to splice uh during that index and after we're gonna say just one very simply if this is for example is is index of one what it's gonna do is it's gonna start over here and it's only gonna splice one because we provided the value of one however if you provided the value of two for example it's going to start here splice this one out and then splice this one out so this just ensures that it's gonna splice out exactly the one that we want and this is actually gonna mutate the real array now at the end of the day what do we want to return here do we want to return the deleted uh the deleted report that kind of makes no sense so maybe we just return nothing and we give it a status code of 204 which is no content so over here we're just going to go ahead and return now you might be thinking well how in the world are we going to give it a new status code because right now let's just go ahead and create a report let's create this new report let's go ahead and look at it so over here you can see it now what i want to do is i want to delete it so if i go to delete and i pass this in you can see that okay it's deleted however the status code is 200 just to make sure that the functionality works this should be gone and it is okay but now what we want to do is well we want to change the status code to 204 just no content in order to do this you might have guessed we need a decorator we actually need the http code decorator and this is very simple we just put it right on top of the method and we're going to say that this method is going to return a 204. so let's give this another go so let's go here let's create this and let's get the id oh my goodness come on where are you there we go let's grab that id let's go over here to the delete and let's pass in this id and now watch the status code 204 no content so that is how we can change status codes and that pretty much um well concludes all of the endpoints all of the endpoints are really just working the way that we want them to however however big however there is a significant number of flaws with the way that we did things like a huge amount of flaws and i did them on purpose uh this isn't the mistake i did them on purpose so we can really analyze all of the flaws and see why they are flaws so let's actually go ahead and try to fix some of these problems in the next videos hello everybody and welcome to this brand new section in the last section we implemented all of the end points as well as the endpoint logic but at the very end of that section i also said that the way that we did things are pretty much wrong there are things that are correct but there's a lot of flaws in the way that we've done this implementation so let's actually take a look at some of these flaws so let's begin with the first one right now our business logic is inside of the controller now let's remember what the controller is for the controller is simply just for creating endpoints so right now what we're doing is we're bloating our controllers with all of this business logic what we need to do is we need to find another entity to put all of this business logic in instead of the controller the controller really just should be for creating endpoints getting the parameter getting the body etc so that is the very first thing the next thing and this is a very important one there is really no validation at this point i said no form but there's no validation at this point let me explain what i mean by this right now if i wanted to make a request to get all of the reports i could very very easily do report slash pickles this is something i could do and at this point we're not validating any of that if we go over here i could also make a request to get a specific report but instead of putting a valid uuid i can put in i don't know 3 which is obviously not euid so we need validation in that front now at the end of the day if we put in something that's invalid we're just going to return null but why even perform this expensive query if we know we're not going to find anything because this is not a valid uuid here is where it gets even trickier right here in the body we are passing in the amount and the source and we're expecting that that amount and source are a number and a string respectively and then we're obviously going to add that inside of our database however what if somebody in the body didn't abide by these rules let me go ahead and show you what i mean so i'm going to go here let's go ahead and get rid of all these other requests and let's go and create a new report and remember in the new report we provide a source and an amount what if instead of the source being a string they passed in an array of objects that has food as a property and then pickles as a value for example something ridiculous like that and then for the amount they passed in false as a boolean well this obviously shouldn't work in our application however when we send it off it does work you can see here we have source which is an array of objects we have the amount which is false not good not good at all so we need to somehow validate that the body that the user passes in is actually the correct body this is actually even more apparent over here with the update because now over here what we're doing is we're actually destructuring out the body so for example right here what we can actually do when we want to update let me go grab let me go grab uh let me go grab this as well as the id that was generated so let's say we want to update and we want to update to this and let's grab this id and let's paste that in there so what we can do is we can even update this this stuff so for example we can even change this amount to um an object that has the key amount and then maybe a number so we can even perform this update but even worse we can start adding additional properties so we can do animal and then rhino we can start adding all these additional properties and they're just going to be updated and added into our uh our report not good at all obviously if i go over here and make a fetch you can see okay everything is fine except once i reach the last one you can see how ridiculous it's looking so again we need to validate the body and make sure that it's the right one and over here of course validate the id just to ensure that we don't even hit this condition the negative one condition so there's a lot of things that are going wrong and in this section what we're going to do is we're going to focus on fixing this over here finding somewhere else to put the business logic but in the next section we're going to work on the validation in the last video we talked about how we shouldn't put our business logic inside of the controllers so where should we well as you know there's multiple entities in nest and controllers are responsible for creating endpoints now in order to put your business logic we're going to put that inside of another entity known as services so let's actually go over here and what i'm going to do is i'm going to go to the app.service.ts file and like usual what i'm going to do is i'm going to completely get rid of everything in it for now we're going to go ahead and build this from scratch so let me go ahead and save it so what we want to do is we want to create a service this is where all of the business logic is going to live at the end of the day what ends up happening is the controller interacts with the service it calls the methods inside of the service and therefore everything works exactly the same however we're separating our concerns now remember all entities inside of nest are classes so what we're going to do here is we're going to say class we're going to call this app service so app service like so now in here we're going to have a bunch of different methods that are going to have this business logic so for example we're going to have a method that's going to get all of the reports so get all reports kind of similar to what we have in the controller and it's actually a common practice to have this method be called exactly the same as this method over here now what this method is going to do is it's going to take in some parameters so what are the parameters that it needs to take in well it really just needs to take in the type of the report that it wants to get so over here what we can do is say type and we can call this type actually the enum type let's go over here what happened here we have double now let's quickly save that what did i do here how did that even happen get rid of that so what we're going to do here is we're going to grab the enum type from the data so from source slash data grab that enum type which is the report type and also let's grab the data itself because we're going to be interacting with the data over here we're going to do report type and what we're gonna do is well we are going to do something like this we're just gonna have this logic so once we have the report type what we're gonna do is we're gonna do this logic right here so this is where the business logic is going to live this right over here we can even change this to type like this because that's what we called it inside of this parameter that's all it is that we have to do the last thing that we have to do is export this out because it is used by the module so now very simply what we can do inside of the controller is just call this method instead instead of having this business logic in and this actually presents another problem how are we going to get this app service inside of the app controller now remember this is a class it's not a function that we can just export we have to instantiate this in some way so how do we do that well let's actually talk about that in the next video we created this service but now what we want to do is utilize it inside of the controller how do we do that well there's actually another entity that's going to allow us to manage dependencies within our directory and that is the modules so the modules is used for adding and managing dependencies between our files so you might be thinking why in the world do we want to export this well it's actually being used inside of the app.module.ts file right here we have an object and inside of this object we have imports we have controllers we also have providers so in this app.module we're saying that the app.controller is the controller and inside of here we have this providers and then we have this app service and right here what this is allowing us to do is inject this dependency in everything inside of this directory which is the source directory so because of this inside of the app controller we can actually utilize the app service we can't do that if this was empty let me show you what i mean now one thing that we missed inside of the app service in order to actually inject it as a dependency we have to mark it as injectable so to do this what we need to do is import a decorator so over here we're going to say from acne sjs common we're going to get a decorator called injectable we're going to go ahead and mark it as injectable now what we can do is inside of the controller remember this is just a very simple class inside of the controller we can have our constructor and we can just very simply inside of the restrictor do a private read only and then we can give our service a name that we want injected into it so we can call this for example let's call this app service app service really we should probably name this to something else and we will later on but for now we'll call it app service and then we can import the class itself and then type the app service with that class so over here we can say import and we want to import from the app service the app service class and then over here we can do app service and believe it or not that is all it is that we need to do so in here what we can do is get rid of this logic and just do just do this because we're referring to something in this uh class then we can do app service dot get all reports and we can supply it with the report type that's all we have to do at this point very simple and we can even put this logic in there however you know this logic is okay to be in the controller just to prove to you that it works let's go ahead and go to postman and let's send off this request and you can see that it's working a okay now let's actually try to remove this app service from here and now let's try to make this request again you can see we're getting an error why is that well let's go ahead and inspect our terminal that's the best way of doing things so let's go here you can see that well we're getting an error you can see that hey we are dependent on this app service but we are not defining it inside of the app module that's pretty much all it is so now let's go ahead and save that and now everything is working fine so the module it seems a little daunting at first but it's really not really it's just a way where we can manage all of our dependencies at this point it seems a little bit unnecessary but when we start having multiple controllers not just one controller so right now we're working with one controller but in a real application we're gonna have multiple controller files multiple services multiple modules etc what we need to do is we need to manage the dependencies between them because we might have one service file that depends on another service file so we can do that inside of the module we're going to see that a little bit in this project but we're going to see that a whole lot more in the next project in this video what we're going to do is refactor all of our business logic inside of the app.service.ts file and we went ahead and we did it for this uh method right over here but now we need to do it for all their other ones so let's go over here let's create another method called get report by id and this is going to take in the type which is going to be the report type it also needs to take in the id which is going to be a string so over here what we can very simply do is grab all of this let's grab all of that let's just paste that in there we're going to go ahead and return and then over here we can just change this to type that's really all it is that we need to do so now over here we can just return this dot app service dot get report by id and we can pass in the report type itself and we can also pass in you can also pass in the id so let's go ahead and do that save that and that's done so now over here we need to create a report let's create a method for this so create a report this as usual is going to take in the report type and it also needs to take in the body so this is going to be the amount as well as the source so over here we can just say um we can call this you really call this whatever we can call this data if we want to and this is going to be the amount that is a string and we have here the body that is also or the amount is not going to be a string it's going to be a number and then the uh the source is going to be a string now this is actually the right way of typing things inside of a inside of a service inside of the inside of this over here the controller where we're getting the body this isn't the right way of typing things we'll talk about how we can type things later but in here this is the right way of doing it so might as well actually just put all this in an interface so over here we can say reports data and this is going to be of type this so we can go ahead and grab that and we can even type it maybe we can even get rid of the data itself you can just grab this and put that in there so over here what we can even do is just destructure out the amount as well as the source good idea so now let's go ahead and uh well grab this let's go ahead and grab all of this logic let's paste it in there we're going to need to grab the uuid so let's go here let's grab that uuid paste it in there so one thing that we are missing is the type so the type here is either equal to income or i think that's okay i think that should work fine i hope so because over here we actually typed that the uh the report type is either going to be an income or an expense so i think that's fine so i think that's that's okay so that's really all it is that we have to do let's go ahead and save that and then in here look at all this stuff that we're going to get rid of we're going to get rid of all this logic so over here we're just going to say return this dot app service starts create reports we're going to pass in the type which is going to be the type here and we're also going to pass in the um the amount as well as the source so say amount and then source over here let's actually do the same logic to get the report type like so and then in here we can just pass in the report type save that and here we can just pass in the the type itself like that okay so that should work we'll test it out later uh now let's move on to the put so this should be update report so update report now what the what is this going to take this is going to actually take a bunch of things it's going to take in the type it's going to take in the report itself and um it's also gonna take in the id so let's pass an id right here in the middle this is gonna be a string okay awesome so let's go ahead and save that and in here there's a lot of different logic that we need so let's just grab all this logic here from here let's cut that all out and let's paste it in the method so let's fix this to type and over here we have the body we can even just extract it like body like this now one thing that i actually missed is we should also update the updated act so updated that we can also over here to new date that's really all it is that we need to do so let's now copy this and in here what we can do is just return this dot app service dot update report and then what we need to do is pass in the report type let's do that let's pass in the id and let's pass in the body very simple last thing that we need to do is the um this controller right here so all we need to do for this and this one's actually simple we can actually extract all of this stuff and put it inside of the delete so over here we can say delete report this is only going to take in an id which is a string and over here you can just pass this logic in let's save that in here we can just do return this dot delete report pass in the id so you might be thinking well this is actually a lot of work for simply moving our logic why do we have to do this this doesn't really seem that necessary well the reason why we want to do this is now we can actually use this uh service elsewhere in our code so maybe it's you needed maybe we need to you know get all of the reports in another service that we create or another controller that we create now instead of having all of our business logic in the controller and the controller is something we can't really import back and forth we have it inside of our service and we can actually do all of these imports and we can do all of the dependency injections so i hope that makes sense i hope that wasn't too bad if a refactor in the next video we're just going to do a little quick test just to make sure that everything is working fine in this video what we're going to do is a quick manual test of all of these different endpoints just to make sure that everything is working a-okay so let's just go ahead with the get request let's go ahead and try to make this so over here you can see that we are getting all of our um reports if i were to change this to expense however we should get back nothing and well now actually no we get back our array right over here of food so this works just the way that we expect it to let me go ahead over here let's actually change the name of this request to get reports we're going to go ahead and save that save this save it all and over here let's actually change this to uid three and you can see that this is working awesome maybe i can zoom out once more like this now let's go ahead and try to create an income report again we can always make this an incorrect body we'll we'll learn how to fix it in the next section but for now let's just make sure that it is correct so we can say source um what's another source of income let's say amazon amazon affiliates or fba let's do that i don't know how to spell affiliate amazon affiliate so we can create this is really good if i go to get all income we should get another one we do so let's try to update this let's try to update this to maybe 6 000 or something so let's go here let's add that let's get rid of this rhino let's change the amount to 5500 or whatever let's actually even get rid of the source completely because we should be able to optionally pick what we want to update and you can see here that we i can update it last thing that we want to do i don't think we've tested this yet let's do the delete we actually probably have let's say delete report let's save that and this time we should get a no content ooh we're getting an internal server error why is that okay this is interesting so let's actually diagnose why we get this error so let's go here close this off maximum call stack exceeded okay so let's get let's let's refresh this and let's give this a call again just to see what happens okay so we are getting an error okay this is good let's see how i debug things i wasn't actually expecting this error so let's let's let's figure out how i would debug things so let's go to the delete and over here okay i can almost pretty much uh i see exactly what's going wrong here and actually this makes the uh this makes the uh error over here make sense so over here what we're doing is it's saying maximum call stack uh exceeded which means we're continuously calling things over and over again and eventually once we continuously call things in an infinite loop it's just gonna say hey you know you hit your maximum there's an error that's going on clearly in your code i hope you can see exactly what the error is by just looking at what i'm doing here so over here i have this delete report method inside of the controller and then what i'm doing is i'm returning this dot delete report so i'm actually calling the same method inside of this method and then once i call this again then it's going to call it again and again and again and again and again forever this is actually kind of known as uh in in algorithms as a recursive function when the function calls itself but we should have some sort of baseline for when we want to stop the uh the recursiveness nature of this function obviously here we don't want to so the mistake that i did was we should have app service here so we should call this dot app service dot delete and that should fix the issue so let's actually give this a quick go again you can see now we get no content and if i try to get all of the reports remember amazon fba if i try to get them again you can see that it's gone okay so everything is working a-okay in the next video let's actually start doing some of the wonderful validation hello my good friends in this video what we're going to start doing is validating the incoming request now i quickly mentioned exactly why and what we are going to be validating but let's actually just look at a quick little illustration here so the first thing that we need to validate is the id that we get back is it eu id why do we want to do this well all of our records inside of our database which is just an array every single record is going to have an id that is a uuid if the id that we pass in right over here is not a uuid then there's no point of actually completing all of this expensive logic we know we're not going to find anything so might as well catch that over here and throw some sort of error so that's the very first thing that we want to do the next thing that we want to do is we want to validate that the body is correct so over here in the body and i showed you this in the last video over here we're expecting an amount that's a number a source that is a string however there's no real way with at the moment with what we're doing of validating that the amount is actually going to be a number or the source is going to be a string in the last video i was you know i made the amount an array of objects and i made the source a boolean so you know we need to somehow validate this so we don't really affect the way the things that we're doing over here the last thing that we need to validate is the type so remember over here we have this type we need to make sure that this is either income or expense we don't want to you know we don't want people to put bananas in there we want them to put either income or expense so we need to somehow validate this now over here uh we're going to begin with this one validating that the id is uuid and this is actually the simplest thing to do and it's going to get a little bit more and more difficult for each validation however i hope you guys understand them there it's going to be still relatively simple so let's get into it the first thing that i want to validate is that the id is actually a uuid so this id over here this id over here this id over here as a quick reminder the request is gonna look like something like this so slash report slash uh income and then slash whatever the uu id is we want to make sure that this is a really a uuid and maybe not just like a number like this or just a random string like so so how do we do that well in sjs there's actually a bunch of entities that we can utilize in order to validate things now these entities or this entity is known as a pipe so a pipe is an entity that can one transform things and validate them let me illustrate this here so over here inside of nest js common what we can do is we can just say pipe and we can see all of the different pipes that we can utilize you can see your parse float pipe pipe parts boolean pipe parts whatever pipe so i'm gonna actually just grab this uh parse int pipe for now just just to illustrate this we're gonna we're gonna remove it later and what i'm going to do is i am going to inside of this param right over here this is the id that we want to validate in the decorator as a second parameter i'm going to say parse in type like so so i hope this makes a little bit of sense so what i'm going to do now is i'm going to go ahead and make this request right over here so this request right over here so localhost slash report slash expense slash seven so that is the um that is the id even though that's not a uuid we'll keep it as such right now so over here let's just go ahead and console.log the id and also what i want to do is i want to console.log the type of id and actually let's remove the pipe for now and then i'm going to add it later just to see what it is so this is without the pipe i'm gonna go ahead and send off this request we get back nothing and if i were to open up my terminal just to see the log you can see here that we get the id of seven and we also get the type of of string all right so this seems like it's working a-okay now the reason why it's a string even though this is seven is because anything that's coming from the path parameter is going to be a string i hope that it is clear so what we want to do is let's say our id is always a number it's always a number what we want to do is we want to ensure that you're always passing in a number to the path parameter and also what we want to do is we want to convert that number from a string to well a number type how do we do that well that's where we utilize the parse int pipe so what this parse int pipe is going to do is it's going to check the id and if it is a string number it's going to validate that and say okay that's fine if it's not it's going to throw an error and then if it's actual string number and it passes the validation it's going to parse it into an integer let me show you what i mean so i'm going to go ahead and save this again make this exact request again and now you can see that it is seven the number you can see that the color changed and well you can also see that the type of it changed as well so that's exactly what this does now what if i tried to do instead of slash seven let me zoom in here once more i did you know slash just some random non-number string let's send off this request you can see that we're getting a 400 error so we get a validation error bad request so that's really what pipes are doing and there's different types of pipes out there so there's a parse boolean type so you know you can probably imagine what this is going to do this is going to ensure that what we're passing in the path parameter is either a boolean or not a boolean and this could also be put in query parameters that we'll talk about a little bit later you have a parse enum type parse whatever type so you can see that there's a bunch of different types that we can use so what what do we want to use well we want to use this parse uuid pipe so what it's going to do is ensure that what we pass in is always going to be a uuid and that's really all we have to do so over here what we can say is uuid and now let's try to make this request again not gonna work it's gonna say hey we expected a uu id so what i'm gonna do is i'm gonna quickly create something here and now i'm gonna grab this and i'm gonna go to the get or the get one and i'm gonna pass in a real uuid and now you can see that it's working now we're just getting nothing back so you can see that it's passing the validation pipe that's that's pretty much it i hope that's pretty clear so let's go here and let's actually pass that pipe in to all of the ids so over here i'm going to parse the uuid pipe and over here parse the uuid pipe i think that's that's all of them so that is the very first thing now what we're going to do in the next video is actually move on to the next thing that we want to validate which i'll introduce in the next video now that we have validated the id with the parse uid type or pipe let's actually figure out exactly how we can validate this type right over here now this can either be income or expense so we're going to need to utilize another pipe for this specifically what we're going to utilize is the enum pipe now this is going to be a little bit different in the way that we use it instead of very simply saying parse enum pipe over here and actually if we save this you can see we actually started getting errors so we get dependency injection errors so instead of using it like this what we need to do is instantiate this instead so over here we say new parse enum pipe and then we pass in the enum so the enum well we already have it as the report the report type and that's really all it is that we need to do so now what we can very simply do is go here and if i were to make this request you can see that it works and actually this is a get request so let's go over here you can see that this is fine this is working a-okay however if i change this to something that's not an expense like bananas it's going to yell at us saying that hey this is not expected and that's really all it is that we have to do so what we can do is we can add this pipe inside of every single instance where we try to get the type and that's really all it is and that's fine that's it all right that's really all that we need to do and now what we need to do is validate the body this is where it's going to get a little bit trickier this isn't going to involve any pipes but rather another entity known as a data transfer object in this video what we're going to start doing is validating the body essentially ensuring that the body has an amount that is a number and a source that's a string and the types are correct that's what we want to do now we can't really really utilize a pipe for this instead we're going to utilize something known as adto a dto is something that we can utilize to transform and validate the body as well as the outgoing response so we actually need to create this dto manually so what i'm going to do here is i'm going to create a new directory called dtos and then inside of the dtos directory i am going to create a report.dto.ts file now in order to create this dto and to have this validation what we need to do is install a few packages so there's two real packages we need to install we're gonna have to do an npm install on class validator so class dash validator and also class tran transformer so let's go ahead and install that and that's really all it is that we need to install now all we have to do is create the dto now all entities are classes so to create the dto let's go ahead and say class and we're going to call this create report dto because this is the body for creating a report you want to validate that this is going to be it well again i've said this a million times but this is an amount that's a number a source that's a string so let's go here and how are we going to validate it well the first thing that i need to do is define the type of the thing that's going to be in this class so we're going to have an amount that is a number we're also going to have a source that's a string so now what we can actually do is extract this dto and actually utilize it as a type so let's go ahead and export this and inside of the controller what we can do is import that in so we can import this dto so let's say from dtos you want the report dto create report dto and then in here in the body we can just say this and this works just just fine get rid of that curly braces so this works just fine it's typing the exact same way that we want it to all right but however this isn't going to do any validation this is just typing in order to get the real validation in what we need to utilize is a bunch of decorators from the class validator library that we installed now let's begin with validating this so we want to make sure that this is a number okay so what we can do here is get the is number decorator and put it right on top so they can say is number but there's actually more validations that we want to do it's actually not enough to just make sure that it's a number we have to make sure that it's a positive number so if it's an income we obviously want to make sure that hey you are making a positive number which is 500 1000 and if it if it's an expense even though it's coming out of our pocket we wanna make sure that you know you're losing a positive number really i mean i know there's cases where there's negative money but in this application we wanna make sure that everything is positive we mark it as an expense or a income with a type rather than the negativity of it so we want to make sure that this is positive so we can actually use another decorator there's so many different decorators like is passport number is phone number is port is positive it's postal code there's a bunch of decorators that we can use to validate it so over here is positive now over here well we want this to be a string so we can say is string another thing is well we don't want the user to provide us an empty string so we can also say is not empty so it is not empty so we don't want an empty string so you can use that as another decorator and that's all it is that we have to do so let's actually give this a quick go now don't be surprised if this doesn't work so we're going to go here we're going to go and try to create something so let's go here and we should be able to create this it works however let's say i made this true it still works so that's that's kind of surprising i thought i thought we did this decorator well what we need to do is tell nest js that we want it to perform this global validation now in order to do this what we're going to do is we're going to go over here to the main.ts file we didn't talk about this but this is exactly where the application is being booted up so we have this thing called nest factory and this is going to generate a new nest application as you can see here and inside of that nest factory we're passing in the root module again we can have multiple modules in our application however we have one root module that's going to be related to all the other modules we're going to pass that module in to create our nest app and then we're going to listen on port 3000 that's why we're running on port 3000 this is just a function we're going ahead and invoking it now another thing that we want to do before we listen is do app dot use global pipes remember pipes are for validation so we're telling it hey we want to use a global pipe now what is the pipe well we're going to import it from nest from nest common and it's called validation pipe at nest common we're going to say validation pipe and then over here we're going to instantiate a new validation pipe so validation pipe and we're just going to go ahead and invoke it like this now we can supply it with some options and we will later but for now let's just go ahead and do that essentially what this says is hey we want to enable global pipes within our nest application so now if i went ahead and tried to send this request ta-da you can see that the source must be a string in fact we can also make it a string if we want to but an empty string and you can see here a source should not be empty what great validation we can use again any form of validation in here we're actually going to look at more validation types in the next project but you guys probably get the point here so now if we supply it with something real it works all right well that is a great introduction to dtos let's now go ahead and do the exact same thing but for the update now this one's going to be a little trickier the reason why is because what we want is the in the body we want the update and the um sorry not to update the uh source as well as the amount to be optional because we might want to update both we might want to update one over the other so we have to figure out how we can do that encourage that you guys do this validation on your own what we want to do is we want to validate the body now you might be thinking we can use the exact same dto however this time what we want to do is we want to validate that obviously the amount is a number and the source is a string but you can optionally give us one or the other so for example if we go over here in this case we're not providing the the source but we're only providing the amount meaning we only want to update the amount we might also want to update the source only and over here maybe change the source to youtube now if we do decide to add something it has to be of that same type so we can't have source equal to true however we don't have to provide both so we need to create a dto that supports this let's go ahead and do that right now so over here let's go ahead and export a new dto so we're going to say class and we're going to say update report gto and then it's going to actually have the exact same validations as we have here except it's gonna have one extra decorator this decorator is gonna be is optional this basically makes sure that this is optional so we're gonna say at is optional so what's happening here is we're saying that this is optional however if you do provide it it has to be a positive number we could do the same thing over here act is optional and that's pretty much it so now what we can do is we can grab this or we can just import it inside of the controller now in here we can get rid of this type and we can just say update report dto and i actually auto imported it we can go ahead and save this and you can see that it's working a-okay another thing that we can actually do is go to the update report and over here you can see that the body is of type report however type reports you can see is um it it's saying that this is a required field so over here what we can do is we can add another interface called update report and say that these types are optional just for better typing in typescript let's say here let's do that and that's fine okay so that's pretty much all it is that we need to do let's just give it a quick test let's go ahead and create a report so we created this report and now we want to update let's say the source to something that's more meaningful so over here let's go ahead and update the source to youtube you can see that it works however if i said source is equal to true you can see we're getting an error uh we can also change it to udemy and over here we can also change the amount to 3 000 we can do all that as well that validation works okay now there is one potential problem so even though it's validating that this exists we can also add additional properties so we can add i don't know um gorilla and we can say banana for some reason and if we actually update this you can see that it works and actually adds inside of the object not good at all so how can we somehow get rid of this additional things that are not defined inside of our dto we'll talk about that in the next video in order to make sure that the only properties that we pass into our body are the ones that we defined in our dto there's one really really small configuration that we have to do all we have to do is go to the main.ts file and in the validation pipe we're going to supply it with some options and so what the first option is multiple options that we can use and we're going to look at a bunch of them throughout this course however the first option is going to be whitelist by default this is false but we want to set it to true basically what this does is it white lists anything that is not defined in the dto meaning that it completely get gets rid of it let me show you what i mean now let's go to the controller and what i'm going to do is i am going to look at this body and i'm going to console.log the body in this put request let's go ahead and console.log the body and for now i'm going to set this to false which was the default so i'm gonna go ahead and make this request let's go over here let's go to our terminal close this off let's go here and you can see that our body has source udemy amounts 3000 and gorilla banana however now if i set this to true let's make this request again you can see that gorilla banana is gone and so what this option does is it looks at our dtos and any additional properties it completely gets rid of it and this is good this is a really good thing for not just the purpose of making our app functional but also for security reasons we don't want people passing in random stuff inside of the body that is not uh intended by our application it could cause a big security risk so we would want to do this definitely so that's pretty much it uh that's all we really have to do in terms of validation we have completely validated everything and now we're ensuring that anything that we get in is proper however then of course we have to start making the requests and stuff but at least in the user side we're making sure that everything is a-okay so that's pretty much it and that actually concludes this section welcome to a brand new section in this section we're going to figure out exactly how we can manipulate outgoing responses what do i mean by that well let's go over here to the data and let's just look at how the data is structured so you can see here that the data inside of our database which again is just a local array is structured where the properties are in a snake case so you can see here if we have more than two letters we're separating them by an underscore so well snake case i hope you understand that and when we send off a response or only want to actually get the data we of course get the data in that format so snake case however what if what we wanted to do is transform this to camelcase so instead of getting it back like this we get it back like this so like so like that how do we do that another thing is what if we do not want to return the updated at we only want to return certain properties again how is it that we can accomplish something like this you might be thinking well what we could do most definitely is selectively pick what we want to return back we don't have to return back everything here we can just do something like this return back an object where the id is the new report dot id and you guys probably get the idea let's just do this one as a whole so source new report.source and then the amount is going to be new report.amount and then for created ad we can actually have that as camel case like so and then we can say new report dot created underscore at and then we can actually completely omit the updated app because you don't want to send that and then we can do the type the new report.type so we can do something like this for sure for every single um controller that we have here or every single service however in my opinion this isn't a great idea and the main reason for this is that there's actually better ways of doing this you can see that this is getting a little long and a little cumbersome so there's actually better ways of doing this inside of nest js and actually has to do with dtos and another entity that we haven't talked about which are interceptors so in the next video what we're going to do is actually create a dto for the outgoing response so what we've been doing so far is making a dto for the body for the request body if you go over here to the controller you can see that we have been creating dtos for the request body however we can also make a dto for the response eventually what is this method going to return so let's go ahead and do that in the next video let's go ahead and create the dto for the response now this is actually going to be one dto that we're going to be applying to almost every single route handler that we want here so let's go ahead and do that so we're going to go to the report.dto.ts file and then in here we're going to create or export and you do dto so this is going to be a report let's call it response dto so what we're going to do here is we're going to type everything so we're going to have a id that's a string a source that's a string and an amount that's a number let's go here put out that number we also have a created at that's a date let's also put a create or update it at updated at that is a date as well as a type that is a report type all right so this is looking pretty good and notice that i also auto imported the report type so this is good however what we want to do now is we want to be able to transform and and do all these different things with our data now when we installed this class validator package we also installed something else called class transformer and over here the class transformer package it comes with a bunch of different decorators that we can utilize specifically we were going to utilize the exclude as well as the exposed decorators so these two decorators we are going to be utilizing beginning with let's begin with the exclude so the exclude is going to allow us to exclude certain properties inside of our object that we want to return now what we want to do is we want to exclude this updated at so over here what we can do is we can do an act exclude and we can go ahead and well invoke it like a decorator so that's going to allow us to actually completely get rid of this updated act so now what do we want to do well we're exporting this uh report response let's call it also a dto so let's go ahead and actually utilize this and just see if it works so what we're going to do is we're going to go to the controllers and inside of each controller method that we have here we're going to specify what this controller method is going to return and it's going to return well we want it to eventually return something that fits this right over here so let's go ahead and do that i'm going to go ahead and save this and we're going to say that this get all reports it returns a report response dto and i'm going to go ahead and auto import it now this is yelling at me over here because now the app itself is not returning that same dto so we're going to do the exact same thing inside of the app.service file so let's go ahead over here and specify that this is going to return a new response dto now the reason why this is failing is going to return an array of new response dtos so let's go ahead and specify that as well as we need to go ahead and grab this so it's returning an array of it over here we need to specify the same thing that is we're going to return an array all right over here this is going to return the object itself so we can just say report response dto as well as over here this one's going to return the object itself updated at that's going to return that the deleted is going to return no content so we don't have to worry about that one over here let's also specify the exact same thing so let's go over here inside of here let's specify that we're going to return that specify that we're going to return this let's specify that we're going to return this and here we're not returning that so that's okay okay so now let's actually give this a go and see if it works so i'm just gonna go ahead and try to get all of the reports and i should not see the updated act uh spoiler alert it's not gonna work because there's a lot of other configurations that we need to do but let's just go ahead and send it off it doesn't work okay so there's actually a bunch of different things that we need to do in order to get this to work and now some of this stuff might make sense however some of the other stuff might be a little bit more complicated and might need a little bit more exploring so let's begin with some of the simpler stuff and then we'll move on to the more complex ones let's begin with the very first thing that we need to do to get this thing to work now right here let's quickly talk about exactly how we're utilizing the dto right now what we're doing is we're just specifying the return type of the function of the method that we end up calling this is fine and dandy but this inherently isn't going to do anything when it comes to transforming our response so instead what we actually need to do is return this report response dto remember this is a class so we can actually instantiate this to create an object so what we can do is we can instantiate this and then we can pass in the object that we have created and then it can do the transformation and well we can return the object that was instantiated from this dto let me quickly show you what i mean by that let's begin with this one because it's probably the simplest so over here let's actually let's go to the service because we're going to do this inside of the service and in here in here let's go to the get report by id so what this is doing is it's going to give us one specific report as you can see right over here so this is going to return to us one one report is either going to return to us null if we can't find anything or the report so what we can do here is we can just very simply do const report is equal to this and then we can just check if the report doesn't exist we can just return early however if the report does exist then well let's return the report so this is the object that we have so what we can do is we can utilize this dto instantiate this dto over here so we can do report response dto and pass in that report once it passes it in what it can do is again it can transform it however now what we need to do is we need to specify inside of our dto that we're able to pass things in so let's go actually go to our dto here and in order to specify that we want things being passed in we do that inside of the constructor that's just basic class stuff i'm going to call the thing that we're going to pass in partial so let's go here partial and we're going to give this a type of partial this is the native typescript type and then we're going to say report response dto so what does this mean well this means that what we can do here is we can pass in any object that is resembling to the one we have here so it doesn't have to be the complete thing it could be partial of that thing so it could have a source an amount it created at it doesn't need to have every field let me show you what i mean so over here we can pass in an object that has an id that's a string however we cannot pass in an object that has this property right here so again it can be a partial of what we have so you can see that works so let's go here let's say report and we're gonna go ahead and inside of the constructor we're just gonna do an object dot a sign and we're gonna this dot partial just so we can assign the object here so that's really all it is that we need to do and as you can see now that's working a-okay so let's go ahead and do that for every single thing so let's go here so this is the create report let's instantiate a new dto new uh what is it called again it's called what do we call it report response dto we're going to pass in that for the updated we're going to do a new response dto oh my goodness i'm almost forgetting what it's called reports response dto go ahead and invoke that like so and then pass that in for the delete we don't have to do that now for the um the gets this one's a little bit more complicated because what we're doing here is we're iterating over everything so what we can do here is actually append a dot map because this is going to return an array and then in here we can grab the report and what we can do maybe we can just return new report response dto and we can pass in the report like that so that's really all it is that we have to do in app controller everything is fine so this is step one now this isn't gonna solve the issue because if i make this request again spoiler alert it's not gonna do anything yet but this was a necessary step to get this to work so that's step number one let's go ahead and talk about step number two later step number two this one's a relatively quick one all we need to do here is tell nest js that we wanted to give it the ability to transform our objects so this again this one is pretty simple all we really need to do is say transform true and this is of course in the main.ts file in the validation pipe we can also say transform options and then in here we can have the uh what was the option called again implicit enable implicit conversion we can also set that to true so this one was really quick and again spoiler alert it's not going to do the trick just yet so what i'm going to do is i'm going to move on to step 3 right away because in this video would be extremely short so step three has to do with the modules so we're gonna go over here to the app.module.ts file and at the moment of time what i'm gonna do is gonna make completely no sense do not worry we're just gonna go ahead and code it out and then i'll explain exactly what's going on later so inside of the providers over here so remember the providers was where we supply all of our services that we want utilized inside of this module what we're going to do is we're going to provide an object this object is going to have the property of provide and it's going to have it's going to have the value of app interceptor now we can go ahead and auto import this in from at nest js core so you can see here uh an sjs core so that is going to be the provide now over here we're also going to supply it with a use class property now this is going to be another thing that we're going to import and this is going to be the serializer class so over here it's going to be a serializer class interceptor the class serializer interceptor and we can import that from at nest common so let's go ahead and save this and again this is going to make no sense but don't worry we're going to explain exactly what's going on here a little bit later we're going to go ahead and save this and now what we're going to do is we're going to make this request and voila as you can see here that our thing is updated how cool is that you can see that we do not see the updated act now before i explain exactly what's going on here because again this is completely makes no sense and it actually is really important that you understand what's going on here because this interceptor thing is another entity that's really important to understand in sjs um let's go ahead and figure out exactly how we can transform this created at from being snake case to camel case let's do that in order to transform something we need to go back to our response dto now before we used this exclude decorator now we want to use this exposed decorator so right over here what we can do is add expose so at let's go over here at expose we can invoke it and then we can supply it with options you can supply it with an option with this curly braces and we can say name and then we can say the name of the property that we want to be called this is going to be created at and then right below it we can specify a method that is going to return the value of this property so you can say here i don't know transform created at transform created that's what we can call it and what we can do here is we can actually get the value of the created ad and just return it so over here we can just do this dot created act that's really all it is that we need to do so now if we went ahead and send off this request you might see something a little bit funky so you can see here we have the created act that is underscore still there but we also have the camel case so what we actually need to do is exclude this created out over here so let's go ahead and exclude that so we can go ahead and exclude it so we exclude this from the properties however we're exposing this right here and just for order sake maybe we can even put that like right here and that should do the trick there we go how cool is that all right so now that we got that working let's discuss exactly what's going on here inside of the module so inside of the module let's quickly remind ourselves exactly what we did inside of this provider's array we added this object we said app interceptor and then over here we said class serializer interceptor now in order to understand this block of code you first need to understand what an interceptor is inside of nest js so let's actually look at a quick diagram to explain this so over here i have a typical request response diagram illustrating how the client will interact with a server now over here we have a client it doesn't really matter what that is could be postman could be a real website whatever a client is going to make a request to our nest api our nest api is going to process that request and send back a response now an interceptor is something that actually lies between the request as well as the response so for example what we can actually do is if we wanted we can create an interceptor where if the client is going to make a request to the server before actually reaching the server it's going to be intercepted by the interceptor in there we can have any sort of processing we can modify the request and then it's going to go ahead and be sent to the server now we can also set up the interceptor where it can intercept the response so before being sent all the way to the client it can intercept it it can do some sort of processing and then you can send it to the client they can probably imagine what this block of code is doing so over here we're saying that we wanted to provide an app interceptor which means that for every single endpoint every single http request we want to apply an interceptor now what is that interceptor well this interceptor right over here the class serializer interceptor now this is a built-in interceptor that comes with nest js and we'll later learn exactly how we can build our own custom interceptors but this right here is a serializer interceptor and if you don't know what serializers are it's just a way that we can modify and change our data so what is happening here well probably what this interceptor is doing is before sending the response to the client it's going to be intercepting it it's going to look at the dtos and somehow modify that response and then send it to the client with the modified response and that's exactly what is happening so i hope this is actually clear now in order to truly understand interceptors let's go ahead and create our own custom interceptor that is going to mock exactly what this interceptor was doing we're going to go ahead and create that interceptor and then use it but then we're going to go ahead and delete it because we'll already have this class serializer interceptor that's going to do our job so we're just doing it just for learning purposes let's go ahead and implement our very first interceptor so what i'm going to do is i'm going to go to the source directory i'm going to create a new file and i'm going to call it custom dot interceptor now in here we're going to create our interceptor now an interceptor is an entity inside of nest js now let's remember exactly each entity in sgs is going to be created by a class so let's go over here we're going to say class and we're going to call this custom into or septor so custom interceptor now i'm going to do something else i'm also going to go over here and i'm going to import something called nest interceptor i'm going to get that from at next common so nest interceptor and over here instead of just doing the class like so which is completely valid i am going to say implements nest interceptor and right away we're getting an error so over here nest interceptor is another class of its own and this class has all the different properties that are needed to create an interceptor in nest so here what i'm basically saying is that i want to create this custom interceptor and i want to i want it to be implemented like a nest interceptor now once i do that what ends up happening is if i don't have the certain properties in here certain methods certain properties that are needed to create a interceptor like it would be created in nest it starts yelling at us so over here you can see here that it's saying custom interceptor incorrectly implements interface nest interceptor it needs to have an interceptor method as you can see here so this is really good this is really good typing that you wouldn't get normally with javascript so now we know we need to have this intercept method so let's go ahead and create that so intercept and this intercept method is going to take in two parameters now it's going to take in the context and the context is not something that we're going to use at the moment but it's something that is going to give us more information about the incoming request so just a quick reminder over here the client is going to send a request to the server but it's going to be intercepted first by the interceptor sometimes we want information about that request maybe you want some query params or whatever we can get that from the context and then over here the next thing that we're going to get is the handler so the handler is the endpoint or the next interceptor that we want to give it to so you want to hand it over to so over here we have the interceptor the handler is this endpoint that we're eventually going to reach i hope that makes sense now what we're going to do here is we're going to type these two things so let's go ahead and do that now this context is going to have a type of execution context and the handler is going to have a type of call handler so let's go here and let's give this a type of execution context just so we can have better typing here instead of having it be any and then here we can say call handler now this is still yelling at us because we have to eventually return something so what i'm going to do here is i'm going to return so i'm going to go ahead and return and what ends up happening here is this actually returns an observable if you don't know rxjs it's completely fine but if you are familiar with it it's going to return an observable again not not really important you just need to understand the structure of this let me let me quickly explain so it's going to return handler and then we're going to say dot handle and then if you're familiar with rxjs this is where it's going to become more familiar we're going to say docked pipe and then in here what we're going to do is we're going to import something called an operator from rxjs so over here we're going to import from uh rxjs where is that rxjs we're going to import an operator and we're going to specifically call this map now there's multiple different operators out there we're going to use the most generic one called map again if this doesn't make much sense to you this isn't an rxjs course um again i'll i'll show you what you should understand from this process later if you want to go into more and more detail then maybe it'll be worthwhile to learn rxjs so over here we're gonna say dot pipe and then inside of here we're gonna have map so we're gonna call map and map is gonna take a callback function and inside of this callback we're going to have the data so this is the data that we're actually going to be passing in so over here oh sorry other this is the data that we're going to be getting back i'll explain that in a bit and then over here we can go ahead and return the data whatever we can do whatever it is that we want with it let's go ahead and return it so what's going on here so we created this interceptor method and might as well go ahead and export it because we're going to want to use it eventually so anything that is inside of this pipe so anything that's inside of this pipe so inside of this map method is going to be handling the outgoing response so anything inside of here is going to be handling the outgoing response now anything that's not inside of the pipe like over here let me go ahead and console.log console.log this is before this is before or this is yeah this is before the request or i guess this is during the request or you know what this is intercepting the request and then anything over here inside of the pipe this is intercepting the response so let's go ahead and um let's go ahead and actually utilize this interceptor so i'm actually not running my application at the moment let's go ahead and run that so i'm going to do an npm run dev npm run dev we're missing that ah sorry you guys i forgot the let's look at the package.json here uh npm run start devs that's what it was okay let's open that up again i'm going to do mpm run start colon dev just so we can start up our app cool and now what we're going to do is we're going to utilize this custom interceptor inside of this module right over here so from that new interceptor file we're going to import that custom interceptor so from this file custom interceptor we're gonna get custom interceptor like so we're also gonna utilize the custom interceptor instead of the uh class serializer interceptor so i'm gonna do is i'm gonna go ahead and save this let's open up our terminal again and let's go to postman and what i'm going to do is i'm going to create a report so let's go over here let's create an income report i'm going to say udemy and i'm gonna go ahead and create this so you can see that it's working fine now you can see actually let me zoom in here a little bit you can actually see that the interceptor is not doing anything which makes sense because we're not really doing any logic inside of our interceptor at the moment you can see here that we're not really getting you know any those changes that we truly desired so over here you can see that our interceptor is working so over here this is intercepting the request and then this is intercepting the response so you can see that this is working a-okay so over here let's actually go ahead and also console.log so inside of the intercepting the the the request let's console.log the contact so we can just see it a little bit better i'm going to put it inside of an object as well so i'm going to console.log the context and then in here i'm going to also console.log the data so this is going to be the data that's going to be in the response let's just see what happens here let's go back to postman let's send off this request okay so over here you can see the context so this is the context this is the data that we're getting from the incoming request you can see we have the arguments we have a bunch of different information that we can utilize in order to manipulate the request in any way in this video where we're gonna actually create this custom interceptor we're not going to really be dealing with the context specifically i'm more interested in this right over here so you can see over here we're actually getting back the data that we want to send back to the client so what we can actually do here inside of the pipe itself is actually manipulate that data so how do you think we can do that well what we can do here is we can say const response and we can say that the response is equal to an object and we can destructure out everything that is already in the data another thing that we can also do is camelcase create that that's eventually what we want so we can add this new property and we can say that this is equal to data dot created at now also if you want we can actually go ahead and type this better so we can actually know exactly what the types are i'm we're going to delete this so really no point of doing that at this point so over here we have that response now another thing we can do is now what we want to do is we want to delete the created underscore ad as well as a delete the created updated underscore act so over here what we can do is we can say delete and we can say response response and then we can say dot oh my goodness response dot updated underscore at and what this is gonna do is gonna delete that property from this object so let's go ahead over here and let's also delete the created ad created at now by the end of it we can actually just return the response instead of the data so now let's actually see what happens so let's actually get rid of these logs no need for that anymore so let's see what happens here let's go ahead and send off this request let's open up our terminal first close that off let's send off this request and now you can see tada we're getting the exact same thing and that's exactly what that class interceptor that we have over here is doing this one's a little bit more nuanced just actually looking at the dtos and looking all of the different things but that's exactly the same concept it's looking at the dtos looking what we want to exclude so it goes ahead and excludes it and anything it wants to include it goes ahead and includes it so you know very simple stuff i hope you guys kind of get the point here all right so that is our very first custom interceptor now we're not going to be utilizing this interceptor i won't delete it just for you know documentation i guess uh but what we're going to do is we're going to go ahead and not use the interceptor though so we're going to get rid of that interceptor and then in here we're going to use that class interceptor because you know why are we reinventing the wheel so let's go here and save that so that's pretty much that's pretty much it that's pretty much all it is that we need to do and that's going to result in the same response ta-da there we go and that actually almost concludes our uh our application now there is one more thing that we need to talk about and that is um how we are actually structuring our files this isn't the best way of structuring files we'll talk about how to fix that in the next section all right my good friends before we actually conclude this i want to create one more endpoint now this endpoint over here is going to be a summary endpoint so we're going to hit something like slash summary and in here what this is going to do is return an object and inside of the object we're going to have our total expenses so it's going to calculate our total expenses it's going to calculate our total income and then it's going to calculate our net income so the total expenses minus the total income or the other way around actually total income minus the total expenses so this actually presents a new problem how are we going to create a new endpoint with a new path if we go over here to our app.controller so this app.controller you can see that the only path that we have right now is slash report slash whatever the type is so slash expense for example however what we want is slash summary so how are we going to do this well there's actually a very simple solution we're gonna need to create a new controller in fact we shouldn't even have put all of our code inside of this controller in the first place this actually should have been in his own controller and we should have another controller for the summary so let's go ahead and create a summary controller and then what we're going to do is uh well we're going to also create a report controller to house this stuff then we're going to empty out our app controller so let's go open up our terminal and now we're going to start using the cli again so remember that cli we used to create the project well now we're going to use it to create some entities so the first thing that we need to do when we want to create a new entity is we need to create a module every single entity needs to have a module so over here we're going to say nest and then g for generate and then we're going to say we want to generate a module now specifically we want to generate a summary module so that's just going to be the name of it now over here once that happens give it some time inside of the source directory let's give it some time it takes some time this this next cli let's just wait years and years and years and years and years and there we go so now you can see that it has created this module for us and actually put it inside of this directory now also specifically what it did it also updated the app.module.ts file and we actually need this to happen in order to utilize the module so what it did was it actually imported that summary module and it put it inside of the imports of the app module now what's happening here is that wherever that this summary module is going to be used or sorry so whatever is inside of this summary module is going to be imported into the root app module and this is going to be imported inside of our nest application so that right there is the module so let's go ahead and now create a controller for this and we as well also create a service so we're going to go over here we're going to do nest generate and this time we're going to say controller this is going to create a controller for us now notice what's going to happen it's going to update the summary.module.ts file so over here you can see that it created a controller file and also created a spec file this is for testing we'll talk about that in the next uh next project and then also updated the summary.module so you can see here in the summary.module we are now specifying that there is a controller called summary controller now by specifying that inside of the app.module we're importing that summary module so it's going to know about that summary controller so the last thing that we need to do is create a service for this so let's go ahead and do that so let's go ahead and create a service and that's pretty much all we need for now so in the next video what we're going to do is instead of diving deep into actually coding out this stuff what i'm going to do is i'm going to create a report directory with a report module with a report controller as well as a report service we're going to move all of this logic in there so let's go ahead and do that in the next video let's go ahead and create a controller for our reports so in here we're going to do the same exact thing we're going to generate the module first we're going to generate a module we're going to call it report let's go ahead and do that again it's going to take some time i hate how long it takes yes i do very much just like how long it takes to generate something so now let's go over here let's also create a controller for the report and we're also going to create a service so let's go ahead and wait now the last thing we need to do is create the service so let's go ahead and do that sir this all right so now let's actually go ahead and start extracting some of this code and moving it in here let's actually begin with all of the service stuff so this is actually going to be relatively easy all we really have to do is just copy this code and paste it inside of here so inside of the inside of what we call the service oh we should have called that report okay we made a mistake here let's go ahead and delete this we have a controller okay so we created what do we have here why do we have this this is kind of strange let's go ahead and delete this we did not want that now this probably is going to cause some issues across our application let's go ahead and take a look exactly what those issues are so you can see over here we're missing a service controller this is probably going to be inside of let's see here what file is this in this is in the app module so let's go to the app module and let's just clean up that mess that we made or that i made maybe you guys didn't make that mess let's get rid of that and let's also get rid of this there we go but now you can see we also have the summary module as well it's a report module in there so what i'm going to do is i'm going to go to the report service file and i'm going to just paste all of our code that we did right here now in here let's go ahead and just fix the import so we're going to say source.dto just so we can import it from the root and we're also going to call this report service so that's all it is that we need to do really really simple let's do the exact same thing for the controllers but before we do that let's go ahead and empty out our service we don't need that anymore so we don't need any of this stuff it just could be an empty uh class so you can get rid of all this i can get rid of that we can get rid of this interface we can get rid of this interface it could just be an empty class we're not really using it at this moment so now what we need to do is do the exact same thing for the um the app controller so let's go here and let's paste that logic inside of the reports controller now notice the report controller actually already has the report path but what we need to do now is just add the type path so well let's just go ahead and just paste that in anyways it's not going to matter let's go ahead and paste that in and then over here over here we're importing the app service now what we want to do is we want to import something else called well we're going to call this the report service because that's what we're trying to get we're going to get that from the report service let's also get this from source and that should fix most of the import issues over here now what we can do is we can call this report service you can also call this the report controller and over here we can call this report service now we're going to need to change the report service on each one of these things over here so let's go ahead and do that hopefully this isn't too big of a refactor it isn't actually but sometimes people get annoyed by refactoring that's pretty much all it is we're done that's that's really it uh the last thing that we probably should do is just delete everything inside of here so let's just grab everything and just leave an empty class in here so let's go ahead delete everything now we have this empty class let's get rid of this and let's just get rid of everything in here other than the stuff that we need to import so let's just delete everything let's just auto import the controller there we go so this still should work the way that we expected let's see if we get any errors inside of our terminal so let's go here seems like everything is working fine let's actually go ahead and test everything so let's try to get all of our reports our income reports we get back um well we get back this over here our hard-coded reports let's try to get back our expenses you can see that we get back our hard-coded expenses let's go back to income um let's go ahead and create a report let's see if we can do that yes we can let's try to get that report yes we can get that how cool is that now let's go ahead and try to specifically get one report so let's go here and just say slash report and this should be slash income let's go ahead and make that request that still works let's try to update something now so let's try to update an income report let's go to our body let's uh let's change the amount to let's cover the source let's change the amount to 1 million because i'm very rich very very rich is that even a million or a billion i think this is 100 million why not i'll take that that works uh and then all we need to do is delete some i'm assuming that works i'm not even gonna test it so now you can see that we're actually separating our concerns into separate um folders and this this is the the best practice of doing things obviously we don't want to stick it stick everything inside of the app controller so as you can see everything is fine so now let's go ahead and actually start working on the summary controller and when we start working on the assembly controller it's going to actually present us with a little bit of problems now that we got that settled let's go ahead and start working with our summary controller so let's go over here just wanted to go ahead and close everything and inside of the summary controller we're going to create a new endpoint and this is just going to be called get summary so get summary and remember what this is going to do it's going to return a total of our income total of our expenses and the net income so total income minus total expenses so over here what we can do is we can create this uh method and right on top we can use a get decorator for this this is going to be a get request and this is going to be a get request to slash summary because well it's the slash summary now in here what we're going to do is we're going to call a specific service and what service are we going to call we're going to call the summary service which we haven't created so let's go ahead and open up our terminal and let's do a nest generate and we're going to generate oh i see what i did there so i'm gonna generate a uh service and i'm gonna call this service what am i gonna call the service summary so now that that is gonna do its magic let's just wait a little bit to create that service five four there we go so oops so right in here what we're gonna do is we're gonna grab the service and inside of the service we're gonna have our logic in order to of course create the summary as well as i mean do the logic to get the uh get the expenses and the income you guys get the point so we can go over here we can create a service called calculate summary and for now we'll just leave it empty and then in here what we'll do is we'll just going to do a return and let's go ahead and actually inject that service in through the constructor so we're going to say constructor we're going to say private private read only i don't know if i did that with the other service let's go ahead over here just to see that inside this controller i do read only on this one yeah i did read only this just basically means that we don't want to modify it in any way we just want to be able to utilize it so read only we want to get the summary service and we're going to type it with the summary service class so summary service like so all right so that's pretty much all it is that we're going to need to do and then over here we can do this dot summary service dot calculate summary so let's go ahead and save that so in here this is where all of our business logic is going to live now the first thing that we need to do is well we need to get all of our income as well as all of our reports so what we could do is we could do that manually like we could go over here and you know import the data and start doing that our service manually however there's really no point of doing that the reason why is because if we go over here to the report service you can see we actually have a method that does that for us so instead of writing this code over again might as well use this method now this is actually going to present a problem to us how are we going to get how are we going to inject this report service from this directory into the summary directory inside of the summary.service.ts file how in the world are we going to do that well you might be thinking well we can probably do the same thing that we've been doing so far you can go here you can say constructor we can say private read only we can call this the report service report service and then we can type it with the report service i'm going to go ahead and auto import that in looks like it's not auto importing that's okay let's go ahead and actually manually import it so from source slash report slash report service let's go ahead and get that report service and then we're going to say report service here okay so you might be thinking that this is fine however let's actually go over here and let's take a look at what's going on here i wasn't expecting this error let me go ahead and just comment this out let's save this up okay so it's go it's working now it's working a okay what i'm going to do now is i'm going to uncomment this i'm going to go ahead and save it we're going to get an error right away now ness js does not understand this dependency one bit it does not know what this report service is and this is why what we need to do is we need to inject this service inside of the summary dot module dot ts so over here what we can very simply do in order to get this to work is from the uh from the source dash report slash service what we can do is we can actually provide it as a provider so you can get the report service like so now let's go take a look at what happens once we try to execute this let's see if the error goes away so i'm going to go ahead and save this and now it understands exactly what it is now this is one way of doing things however this isn't actually the recommended way of approaching it why well inside of our um inside of our reports we could have multiple services and we might need to import multiple things from this report directory so it's actually a better approach than rather than importing every single service manually to get rid of the service we're not going to import this service but rather we're not going to put the service inside of the provider rather what we're going to do is we are going to put this inside of the import so what we're going to do is we're going to import the report module as a whole so the report module as a whole so now what i'm going to do is i'm going to go ahead and save this and this is actually going to give us an error so if we want to import the report module as a whole then what we need to do is we need to go to the report.module.ts file and explicitly say what we want to export so meaning any module that is going to import this report module is going to get the services and the controllers that we explicitly export from the report.module.ts file so that doesn't make any sense let me explain over here we're going to provide another property and we're going to say that we are going to export the report service now if we have multiple other services in here we can add them in so i don't know another service right in here now for now we're well because this is the only service we have we're just going to export this service so what's happening here is when we import the report module in the summary.module.ts we're going to get everything that it exports which is the report service so now if we go ahead and save this you can see it is working a okay this is actually a better approach importing the module as a whole rather than nitpicking every single provider all right so now that we got the imports all done that's pretty much really all it is that we need any kind of a new concept in the next video let's actually go ahead and actually implement the logic to create the controller as well as to conclude our application let us conclude this application by moving into the summary.service.ts file and in here let's go ahead and implement the calculate summary logic now as a quick reminder eventually what we want to return is the total income so for now i'm just going to leave it as an empty string or maybe a number that would make more sense the total expenses save that as a number and then the net income which is going to be the total income minus the total expenses so in this case 90. we'll leave it as that mathematical calculation for now so first thing we need to do is we need to get the total expenses so let's actually use the report service for this so for this let's go over here to the report service just so we can get some clear idea of what's going on so we have get all reports so i'm going to go over here i'm going to say all expenses i'm going to say that this is equal to this dot report service dot get all reports and we're going to supply it with remember we have to supply with the enum i'm going to go ahead and auto import that enum in as you can see it auto imported and for now we're going to get all the expenses so dot expenses so this is going to get us all of our expenses inside of an array so this isn't really what we want what we want to do is we want to get the total expenses so what we can actually do is we can actually reduce down this array to a number by utilizing the dot reduce built-in method so the dot reduce built-in method so what this dot reduce is going to take is first of all the accumulator so the accumulator is this thing that we eventually want to compress it to we want to compress it to a sum so we're going to say sum and then it's also going to take in the current element that we're iterating over which is the report now another thing that we need to pass in other than this callback is the initial value of the sum which initially will be zero so over here what we can very simply do for each iteration of the report we can just simply return the sum plus the report dot amount and what this will do is just going to compress this down to the a number which is going to be the total expense let's go ahead and do the exact same thing for the total income this is going to be very similar total income over here and this time we're just going to need to change this to income and then over here what we can do is instead of actually hard coding the code we can start utilizing these variables and then for the net income you could just say total income minus total expense so total income minus total expense and that's pretty much it and that should conclude because our controller is actually already utilizing this this function so best thing to do is to go ahead and test this out so let's go to our app.ts file remember we have some hard-coded things in here so we have a a a salary here of 7 500 we also have an another income of 2500 and we have this food for 500. so for income we should get 10 000 for expenses we should get 500 and then for the net we should get 9 500 if this works properly so let's go ahead here and let's uh just save some of these requests let's get rid of them let's copy this let's get rid of that get rid of that let's go here and we're going to call this request get summary i'm going to go ahead and paste that in the url is going to be let me zoom in here the url is going to be summary let me zoom out we're gonna go ahead and make this request and well as you can see it is working a-okay so that pretty much concludes this uh project i hope you guys learned a lot uh and this is gonna be a huge foundation for the next project but we're gonna learn a lot of the more advanced concepts so this is where you're actually gonna start becoming a real nest js expert you're gonna know a lot of these different things that most sgs developers don't even know so well i hope you guys enjoyed that and i'll see you guys in the next
Info
Channel: Laith Academy
Views: 36,340
Rating: undefined out of 5
Keywords:
Id: BiN-xzNkH_0
Channel Id: undefined
Length: 201min 58sec (12118 seconds)
Published: Sat Feb 19 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.