Nest.js REST API with CORS, Rate Limits, Server Logs, & Exception Filters

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello and welcome I'm Dave today we're going to add cores rate limiting and more to our nestjs rest API and I'll provide links to all resources in the description below I'll also provide a link for you to join my Discord server where you can discuss web development with other students and you can ask questions that I can answer and receive help from other viewers too I look forward to seeing you there this tutorial is lesson six of a JS series and today's starting code is the completed source code from lesson five if you haven't watched the previous lesson there's a link to the playlist for this series in the video description and I recommend you start at the beginning as each lesson will build on the ones before it today we will add cores rate limiting server logs and an exception filter for improved error reporting especially with Prisma that we introduced in the last lesson now I've had requests to add microservices and authentication to this series but I think those topics Both Deserve their own minseries of videos so today will be the last video Lesson of this nestjs for beginner series and we will have completed creating a rest API that you can deploy as you would any node.js application we're starting in the docs today and we're looking at the global prefix and as you see they attach it directly to the app that is set in the main.ts file that we have and it adds a global prefix now now we were previously requesting uh things at the employees endpoint but now we really want to attach API because most apis use that and that of course says where our API is so we want to go SL API slm employees or to whatever other resources we would create and we can attach API to all of those resources if we put a global prefix so let's go back to VSS code and add that first we're back back in vs code I have the source directory open here in the file tree I'm going to go to the main.ts file you can see we have our app right here and then we await and have app. listen on Port 3000 but in between those we can actually attach our set Global prefix let's say app. set Global prefix now inside of here all we need to do is put API it will handle the slashes in between each level for us and now we're back the docs and we're looking at cores cores stands for cross origin resource sharing it's very important when you're setting up a rest API and if you've worked on the front end at all you may have received a response from a request that said the cores header did not exist so you know it's probably important that we configure cores so people that are not on our domain at another origin so cross origin can actually request some data from our API now we can keep a list of of allowed Origins and only let those domains access what we have at our domain but if you just set it up like this where they show enable cores essentially you're opening it up for everyone so if we wanted to have a public rest API we could just say app. enable cores and that would open it up for everyone however cores does take an optional configuration object argument and it's no different than the typical package we would use if we created a rest API with just node.js and express and in fact we used that exact configuration in my node.js for beginners course and there's a link to that in the GitHub repo for this series because it was a recommended prerequisite now let's go ahead and quickly look at that configuration I'm not going to use it today but I'm in my GitHub repo for that nodejs course and we can see this configuration right here it defines origin inside of an object and it has a function in here and that's all explained in that other video I'm not going to go back through it but notice it's using allowed Origins that are imported and you can see in the allowed Origins file that I just put in say yoursite.com whatever your domain would be and then typically what we would have at least what we had at the time when we were running anything on our local host in Dev mode so there were those options as well but anyway you can get all of this in my node.js course and that is linked in the readme for this nestjs series as a prerequisite so now let's go back to vs code and enable cores so we can at least have a public API and everyone can request our resources okay we're back in VSS code right where we had the set Global prefix let's go ahead and add another line right before that and let's say app. enable cores and of course we need the parentheses to call that into action and there we have now configured cores very easy in nestjs but again I emphasize this is opening it up to everyone so cross origin requests are allowed you would need to add that configuration object if you wanted to limit who could access the resources through cores and speaking of limiting we are now discussing rate limiting here in the docs you can see we need to add another dependency as we add rate limiting it says npmi we don't need the D- save that happens automatically anymore but then at njs throttler so let's go back to VSS code we'll add this in and I'll show you how to implement it back in vs code let's open up a terminal window I'm going to paste in what we talked about npmi at nestjs throttler let's go ahead and add this as a dependency to our rest API project here in nestjs it shouldn't take too long and then we'll go ahead and apply it to the project and we're not going to do that in the main TS we're actually going to do that here in the app. module. TS file so let's start with the Imports we need at the top so we're going to import Rottler and then module and then we also need throttler I spell that right a strange word actually throttler guard there we go from nestjs throttler we need one more import so we're also going to import now this is all caps so appcore guard and that is going to come from at nestjs there we go let's go ahead and save those changes now we need to apply that to our module underneath the Imports are getting a little long I'll scroll up here and let's put each one of these on a different line so we had started out with a users module example in the earlier lessons then we added the database module and the employees module that's all good now we need to add the throttler module here so I'll put one more comma after that and on a new line let's have a line in between there we go Rottler module I seem to have a hard time typing that one for root now inside of the parentheses we need to start an array and then an object now there's two values here TTL so time to live going to set that at 60,000 these are milliseconds again and then I'm going to set this really low so you can see what happens when we exceed the limit so I'm going to set this limit to three and if there's any confusion here 60,000 would be 1 minute so only three requests in one minute that's super low I can easily exceed that 1,000 milliseconds would be 1 second but we're not quite finished because we also need to do something here with the provider so after the app service let's put a comma and now let's start an object and now inside of this object we're going to say I need lowercase provide and this is where we'll use the app guard that we imported after that we'll say use class and this is where we'll put the throttler guard that we imported and now that should apply the throttler module essentially rate limiting our entire application now we will look at how to override this on a Prem module basis or actually also a pre- route basis so you can drill down to each thing and override the default that you have set or defaults as we'll soon see but let's go ahead and look at what error this gives and to do that we need to go ahead and start up npm Run start colon Dev and we'll get our rest API going and then we need to make a request to are now SL API slm employees endpoint I'm going to use my built-in Thunder client extension as I have in this series you could use whatever you want to whether it's Postman or some other piece of software that used to send requests and now you can see here let's see I've got a fake roll here of pasta let's remove that and now we've got SL API SL employees also since we're in a Dev environment make sure it's just HTTP and not https I'm going to send a request it's good that's fine we got all the employees let me send it again and again we've hit our limit of three I send number four we get a stat St code 429 throttler exception too many requests that's exactly what we wanted we have limited the amount of request any one client could make from our API again I set that way low let's go back and look at some other settings that we can put in Back to the app. module. TS file we'll look at the file tree over here again now instead of just this one setting we can actually put in some named settings so let's do that we start with this object here let's go ahead and give it a name and let's call this one short now for our time to live let's make this one second and let's say we want no more than three requests in any one second that's a little bit more realistic from the same client again not in total from everyone now besides that we can add another object here with another name so I could just copy this object again and then we could change some values so I'll paste that in here let's call this one long you could have more than two if you wanted now for long I'll put this back to 1 minute and let's say we want no more than 100 requests in one minute so two different values now they both apply also so no more than three requests in 1 second and no more than 100 requests in any one minute duration I'm not sure I could click fast enough to show this example but I'll leave this in the code just so you have it here now let's look at how we can override this inside of our employees resource let's open up the employees directory and go to the employees controller here we need to import skip throttle if we're going to use it and throttle if we're going to use it so I'll import both throttle and Skip throttle and those are going to come from at nestjs rler there we go now that we have both if we wanted to skip the throttler essentially the rate limiting for this entire resource this entire controller we could just say at skip throttle and call it right here at the top above the controller and that would skip it for everything inside this controller so that's one possibility another is let's say we wanted to skip it for most everything but we wanted to apply it to our get all where we get all the employees here or find all method under our get route and here we would put another skip throttle but now inside we pass an object and we would have default and here we would say false it accepts a Boolean value so the default is actually usually true so when you just say skip throttle and call it it's going to skip everything after it but now if we put this decorator for skip throttle just above this get request to find all the employees then it's going to go ahead and rate limit this particular G request so that's a nice addition besides the control we have at essentially the global level for our application but now let's say we wanted to override the defaults for a different route of course you could do this for the entire class as well here at the top of the controller but let's just do it here for our find one route that's also a get request so above this I'm going to put rler now inside of here we pass an object as well now previously we had some other uh names already we had short and we had long instead of just default so we could override that we could say short here we could have an object you have to have the same values so time to live let's say in what what was that that was like uh I think it was in one second we said no more than three requests let me quickly look at that object once again so yeah limit is the next one so here we have the name but it's different we don't have name short we just have short here with an object so now we say limit and let's say we're going to limit this to one request because I might be able to actually exceed that and I seem to have a typescript issue here I don't think I did this right throttler doesn't seem right yes I imported throttle not throttler so need to remove the r there and now we should be okay so oh we need The Decorator in front of it as well so I totally messed up I added an extra character here and I left the decorator off the back so here we have at throttle it is a decorator now we have our named uh rate limiting that we previously defined an app module of short and we're overwriting that we're still saying 1 second but now we're saying a limit of three you can do that if you don't have any named if you set it up like I did in the very beginning before we had any of these named settings you can use default here and you can override your default as well so either one works we'll call this short let's go ahead and save this change now I want to make a request again to API employees and then put an ID after it and I want to try to make more than one request in one second let me see if I can do that so back here in Thunder client we had too many requests before but now we should be okay for the first one I'm going to request employee with an ID of one and let's make sure we can get that data yep that's me there so okay now I'm going to request it twice in 1 second if I can yep we've got a 429 because we were able to override that short setting on that one specific route in the controller by passing the at throttle decorator once again after I corrected myself overwriting that short value that we set in the module here with the name of short now you don't have to do that but it's nice to have that option and now you know how to add rate limiting at the full global app level as well as to any controller and also to Any Given route override any of those you want to or skip any of the rate limiting you want to anywhere you want to we're back in the docs and looking at logger under techniques for logging in the nestjs docs now I want to say right up front that many deployed applications make use of other logging packages like Winston but we're going to quickly look at what is built into njs and we're going to use it today as we create an error exception Handler that grabs all of the errors including those that we might get as validation errors from Prisma and so we'll throw that together fairly quickly and it just gives you another option in your skills so let's start by looking at the basic customization and you can see we're going to bring in logger here and we could just set it to false so we're actually not Lo in anything and as you might guess you could also log everything so after that we want to look at what else we could set logger to if it's not false and here we can give it an array and we can choose several things log fatal error warn debug and verbose we can choose any of those we want of course every time we make a save and make changes in our Dev mode we're going to see the nestjs server reboot with those changes you'll see a lot of log messages as everything starts up we're going to move right on to a custom implementation now what you can do with a custom implementation is essentially override the common logger service that is built into nestjs so you can see the class here and it shows you the methods in the class you've got log fatal error Warn and so on you could overwrite all of these we're not going to do that most of these are fine just the way they are and we might not want all of those but of course you could and the code is right here in the docs to grab the skeleton of this class and put your logic in here you might even be writing to a text file when you log these errors as well as sending them to the console in the server so now after we scroll down here it's going to talk just a little bit more about what we can do and one of those things is to extend the built-in logger that's something I'm more interested in doing so now we could import console logger and then we could create a class called my logger that extends console logger and then we could put in any method that we want to kind of piggyback on here so just like the error Handler and then we call super. error so it goes ahead and does what it normally would have done with console logger back in the built-in logger configuration up here in the logger service so if we implement this we might have something we want to use let's go ahead and do that in vs code we're back in VSS code I'm going to press contrl C here in the terminal to stop our server also go to the file tree over here so we can see what's going on we've got our employees here is the app module and now in the terminal I'm going to type Nest G module my- logger and we're going to create a new module and we should see a new folder over here named my logger that has that module in it it doesn't have everything we need by any means but it's a good start we're also going to need to create a provider so a service Nest G service my- logger and now it should create the extra files we expect with a service and there they are and not much in here yet either so let's create the service first and then we'll bring it back into the module now this is going to be as custom as you want it to be so you don't necessarily have to copy mine you'll have mine finished in the completed source code for this lesson but the main thing is to get the concept of how you put this together so after we export the class we want to say extends console logger which we haven't imported yet I was hoping it would just automatically at the top but it's not going to happen so I'll say import console oh we already have injectable up there at the top so let's just go ahead and add console logger right here in this line console logger so it comes from the same nestjs common so we've extended console logger now inside of this class we can go ahead and add whatever method that we want to kind of piggyback on so it's one that already exists in console logger but we want to add a little bit more to it in this case I'll work with the most common ones just log and error so we'll start with log now if we Mouse over let's see if typescript helps us at all it says it implicitly has any here so it's not helping us a whole lot but I do know what error take or what log takes in it's going to have a message and it's typically defined as any here and then context and let's say this is optional and it's a string and you could look back in that logger service to see what these actually are because you want to match these up so now I'm going to combine both of these and we'll say const entry because this is going to be a log entry into a text file log that I keep so we would have a template literal here and I'm going to start with the context going to separate them with a tab which is a backs slash with a lowercase T and then I'm going to put the message so I want a t t delimited log text file that could be imported into an Excel spreadsheet if that's what I wanted to do so after that here I'm going to call a method that's actually going to record that entry into that text file but we haven't written that method yet so here we want super. log and let's look at what log wants here and this is possibly what we need to see no this is not where I saw oh yes it is there we go conso logger.log message any context is optional and it's a string so you want to match that when you are taking in here with log that's essentially what you want so now that we have that we just pass in the message and the context here to the super dolog now of course we're not using entry yet but we will as we write to a text file let's do one more of these let's start with error and now we don't know what error takes in yet either so let's do this the way that would make sense and that was if you were to call Super and now also have error here and then let's look at what error wants here and we see it up above message any stack or context string and I think you could just copy it right out of here you sure can with contrl C we can put that in there that's what should be called with the error and I totally wasn't thinking because I put it in the wrong spot it shouldn't go in there even though we read it from there it should go in up here and that's why it should match here's where you're actually calling it so it wants the message and it also wants the stack or context and now it's going to be happy as well anything else you want to do can come before that once again I just want to Define that same entry with the context and the message and we would eventually write to an error log here if we wanted to as well actually it's not context it's stack or context that we would have right there so just a little different that you have to customize and now whatever would normally happen inside of the eror could be here and I don't really think we need to have those curly braces because I didn't with log either we just call it with super. a and that should be good so if we wanted to write to our text file it would be in between both of these and now I'm going to add some nodejs code that was very similar to what I had in my node.js for beginners Series so I'm not going to go over every little bit of it with you but it's just about creating a log file directory and writing or appending to that log file if it exists and if not creating it so we've got a few Imports up here with the file system promises from the file system promises and path after that I'm just going to paste in my function that is called log to file here it'll actually be a method inside of my logger service is what this is called and we could shorten that to my logger but my logger service is just fine and I put that in so so I can wrap that down with alt Z quickly show you what I'm doing it's an async method it accepts that entry that we are creating I'm adding to that here with a formatted entry that also brings in the current date and then it ends it with a new line character so each entry is on a new line what happens is it checks to see if that directory logs exists if it does exist then it or if it doesn't exist actually it goes ahead and makes the directory it does exist it just appends to the file and the file is going to be called my log file and of course you could actually add another Pam here to this and you could write to different files if you wanted to pass in the file name all the time and this is in a try catch block as well so that's what we're doing now let's go ahead and call that inside of the methods here because this is the whole reason we added this we extended the console logger so we could add a little functionality well added functionality is to write to these files so inside of our log here we want to say this DOT log to file which is our method and then we want to pass in the entry we defined and I'm going to do the same thing copy that without making a mistake and do the same thing here inside of our error method as well and again if I went too fast on this function first of all I'm going to recommend my node.js course because if you're learning nestjs you need to already know how to do some of the basic things with files in nodejs because that's lying underneath nestjs so you should go back and of course look at my node.js for beginner course and if not this is going to be in the finished source code for this video and now we have just a little bit to do inside of our my- logger do module file so here we have my logger service imported already that's good providers my logger service now we also need an exports here so let's say exports and inside of this would be my logger Service as well and now at the bottom we have my logger module and really that is all that's needed for this file so now if you wanted to use this globally it's not too hard to do I'm not going to end up doing that today but I'll quickly show you how to do it after we created our module it was automatically already imported into the app. module. TS and we see that was created for here it brought it in at the top as well so we should see that import and you should see it in the app module that's fine but that's not the only thing we need we need to go to the main.ts file so if we're going to use this we've got the app module here inside of the nest factory. create method then we want to put in a comma and have an object and this is where we would set those other settings that we briefly looked at like logger false or we would pass in an array and say the different types of logging we wanted like for both but here instead of any of those we would go ahead and put buffer logs and now here would say true and this is because this is outside of any module and you've got to give just a little buffer to make sure that that service has been instantiated so that's what buffer logs is all about now there's one more thing you have to do after that and that would be to say app.use logger now we pass in app.get and here we would say my logger service and let's see yes it imported that automatically at the top for it now that is all you need to use that logger service globally so now it would be active everywhere and that's fine it could get full of a lot of those startup logs as we would restart of course you wouldn't normally restart your server nearly as much as you do in Dev mode but there it is all applied globally however I don't want to use that today so I'm going to remove it you just want to remember how to do it here so I'm going to go ahead and take it out of here and I don't want it with the app module up here either so I'll go ahead get rid of that configuration and remove the import as well we're going to use it individually on a Class by class basis as we want to apply it to Any Given resource so now to demonstrate I'll just give one example inside of employees and you can apply it to other places if you want to the main thing is that you understand the concept of how to create it so I'm in the employees controller I'm going to go ahead and need to import that service so inside of here we'll say import logger service or my logger service I think it's my logger service there we go and now that we've imported that we can go right underneath the Constructor here and say private readon logger let's set this equal to a new new my logger service and now inside of here we're in the employees controller and I want to pass in a context and so this is going to be the employees controller. name so we're passing in the name of the controller now we have a context that will be logged with those log messages so we know where whatever happened happened so let's go down to this find all method that we have under our get route and let's log something so now that we have this let's say this. logger.log and now we can pass in any message we want to here it's ready to go ahead and record and one other thing that I want to do is actually get the IP address of whoever makes this request and we can do that as well with another decorator from nextjs we'll need to bring that into our function also so up here after our query I'll press alt Z so it'll probably wrap down let's also bring in IP with the capital I lowercase p so now we have the IP decorator back in this git route for find all and let's start before the query because it can't be optional uh we can't have something that's required after an optional pram so we need to put the IP first it's going to be required so here we have IP and we call it now we'll say IP is going to be a string so now we have the IP address as well and I'd like to record that so let's first put in a message here that is a template literal quest for all employees and now after this I'll put in a/t for a tab again because I want to keep my file tab delimited again this is a roll your own use something like Winston or something else you probably wouldn't have to do that now I can pass in that IP value so the last value should be the IP address and so we're logging that and it should go into our text file and that's important if we're having any problem with any specific uh user requesting from a specific IP address we're going to be able to record that now as well now what about logging errors well before we do that we want to create our exception filter that's going to grab all the errors that happen everywhere so we can get an accurate record of everything that's going on in our application let's go back to the docs we're back in the nestjs docs and we're looking at exception filters now and this is is under the overview with exception filters now as it says here you may want full control over the exceptions layer well we definitely want some control they give us several code Snippets here here is a common filter you could just copy this code from HTTP D exception. filter. TS and create that file and you could use that we're going to do something a little bit different but I took some code from here so you want to be able to know what this is doing understand understand how this is working you can see it's getting these different values CTX stands for context by the way here's a response here's a request notice they're bringing in request and response from Express which is under the hood and then we're getting the status as well it gets a little more complicated if the type of exception is not just an HTTP exception but possibly any type of exception and they've got a code example for that as well where we're looking at all exceptions and that's more or less what I want to create here so I'm scrolling down I know it's going to be down here soon and they're showing how to apply some of that catch everything so this is similar but a little different notice the catch here does not have that HTTP passed in at all now it's empty and this is going to catch everything and they're calling this class all exceptions filter now I know if you just copy this code it's going to have an issue or two but what you need to look out for what you will identify as the problem is this exception before you can do anything like get the status of the exception that we saw in that previous code example and they use here too you need to make sure exception is an instance of HTTP exception and then it will have get status available if not they're going ahead and providing something else here the internal server error which would be a number I believe like 500 you would typically see with that now the response body is created after that and they're sending a response I'm going to show you my code they give you most all of the code here my code just pulls it together we're back in vs code and we want to create our new file at the same level as our main TS file here inside of the source directory so let's create a new file and we'll call this all- exceptions. filter. TS just like they did in the docs now we've got a few things to import here at the top so let's go ahead and start with that we will import catch and that comes from nestjs common now we need several other things besides just catch we also need comma then arguments poost HTTP status and HTTP exception okay I'm going to press alt Z so that wraps down to the next line now we know we're finished with that line let's go ahead and import base exception filter because we're going to extend that now we also need to import request and response that's going to come from Express as we noted in that previous example as well once we've got those we need to import our logger service too because we want to write to our log so we're going to import my logger service there it is and after we have that let's go ahead and import the Prisma client validation error now Prisma has several different errors I'm just going to show you an example of this one I'll show you where to find the others as well okay I need a response type so I'm just going to put this in here from my previous code I can quickly go over it I've just got my response object type has a status code that's a number time stamp that's a string a path that's a string and a response that can be a string or object now what this is is formatting essentially the model for the way we want to handle our errors and so this gives us control over our application and we'll always be receiving errors with this information filled out so it gives us a little bit more control than just a random error that we might have otherwise okay let's scroll for some room we need to start off with the catch decorator that we imported so we'll call that then we want to export class all exceptions filter and this is going to extend so extends the base exception filter once we've done that we need private readon and let's bring in our logger and we've done this before we'll set it equal to a new my logger service we need to pass in now the all exceptions filter and then of course get the name so that gives it the context which we did earlier for our logger to now we can start our catch which will have an exception that is unknown and of course you can look in the docs to confirm this and then we have host and this is going to be the arguments post so yes I got that right out of the docs so now let's bring in some values similar to what we saw in the example in the docs as well and if I save we might get a better format nope I need to do that so I'm going to tab that over there we go so what we've got here is the context once again response and request those are the examples we saw in the docs now here is my initial response object and I'm setting up the timestamp right away to an ISO string I'm also setting this status code to 200 unless we run into an error or something else where we're going to overwrite that status code and then of course we're going to have the response as well so now in the interest of saving a little bit of time I'm going to paste in the if and then else if statement and we'll look at what it does and I need control+ V there we go I'll also need to format this I think I turned off my format on save so I'll just tab this over looks right now so what I'm doing and this is to help typescript help me as well because the exception isn't always the same type so it doesn't always have the same methods so we need to check to see if the exception is an instance of the HTTP exception then we can use the get status and get response methods to set the status code for our response object as well as the response but for example if it's the Prisma client validation error well then we want a 422 response and I want to get that message and it's a message that's broken into several lines I'm actually using replace all here to replace the line break so we get all of that in one line and it will write neatly to our logs as well as send the proper status code and I do just want to take a second to acknowledge that I put 200 here is the default we're already in the all exceptions filter maybe I should go ahead and make that a 500 because we know we shouldn't be here without an exception that is the catchall internal server error that you would expect a status code 4 that could be our default right here that we're getting from the HTTP status. internal server error as well and our default response of internal server err okay do I have an extra curly brace on wondering nope that is our catch right there and that's green so let me tab all of this in to get it on the right level and now that looks correct to my eyes after that we need to go ahead and send our response so let's go ahead and type response that we defined above and now on the next line let's go ahead and say status and here for status we can just reference our object where we already set the values so my response object. status code and that is what we want send for the status then let's send a Json object for the message or Json string I should say my response object is what we're going to pass inside and send all of those values now we haven't logged anything yet but we did bring in the logger so we'll say this do logger this is where we can call the error method and now we can pass in the exception and you know what since we already have that message let me go ahead and look at that one more time here oh yeah and the replace all on it what we actually want to do is not just pass in the exception we want to pass in the my response object. response that's already formatted for however or whatever type of error we receive so let's pass that in to fulfill that exception now this also needs a host passed in if we look at what we've got here so we've got message any stack or context string no so the host defined let me take a look oh and I know the error this shouldn't be going to my logger here this goes in the next line so I was looking one ahead what I do want to send is the context here this is the all exceptions. filter. name one more time now on the very next line where I was looking one line off that certainly happens to me as well as probably everyone else every now and then I want to send in the exception and the host with the super now this of course is passing on what should be happening already because we extended the base exception filter so now we just allow it to carry out what it would have been carrying out and that completes our all exceptions filter now after that we still need to pull it in and apply it to our applications so let's go to the main.ts file at the top of our file besides the nest Factory we also need to bring in HTTP adapter host from the nestjs core and then we need to bring in our all exceptions filter so here we'll import all exceptions filter now we're finished with the Imports we need to add two more lines to our application here so I'm going to say const and now we D structure the HTTP adapter this is going to come from app.get and now we pass in the HTTP adapter host and now on the next line I'm wondering what's wrong here we have app.get and we didn't set it equal we need an equal sign there I'm creating a typo two long tutorial okay after HTTP adapter we need app.use Global filters and now inside of this use Global filters we'll create a new all exceptions filter and we pass in the HTTP adapter that it expects to receive that completes everything we need now we should have applied this all except filter that will grab all of the errors and of course we need to go ahead and try it out and make sure we're logging the errors we expect to log we'll go control back tick to open up the terminal npm Run start colon Dev and we'll get this up and running we'll make a couple of requests and see if we can create some errors and it looks like we've got an error which isn't surprising as many typos as I've been making let's see what's going on oh we didn't connect to Neon properly let's go ahead and try to restart this one more time that can happen every now and then too let's go ahead and npm run Dev let's see if it starts up correctly now and yes everything is started and it looks good let's go to Thunder client where we can make some requests and let's just request all employees I'll scroll this down we'll bring this down a little bit let's make sure it works and yes we got all the employees so that's good let's make several rapid requests now so two three four too many requests and here is the form or the format that we wanted for our error so we can see status tode 429 We have the time stamp we wanted we can see the path that was requested and too many requests so that worked as expected okay now let's try this one more time and I may have to wait depending on what we exceeded let's set our role let's set it equal to admin and see if we get a successful request yes we have the admin employees so that's good now what if we set this to something like you just saw there like pasta let's see what happens that's not a roll ah now we got our 422 because that was a Prisma validation error so you can see the path that was requested and we have this long message as a matter of fact it breaks down to several lines even though we made it return on one line because it's long but when we get to the end of it at least Prisma gives us something that we can definitely understand invalid value for argument roll expected role so pasta is not a valid value for that so it says invalid right here at the beginning as well but we can figure out what we want from those messages so we've got the 422 that we expected as well everything worked well there as far as what we wanted in a response let's look at the file tree now and see if we have a logs directory and we do and we have a my log file let's check this out so we had a request for all employees now something came in undefined here which I believe that's the context we might want to see if we did something wrong there but yes the context with all exceptions filter is good here so that's important let's go ahead and see if everything else came in as expected yep the too many requests problem that's fine so everything's recording we just have an undefined value here that should be the context for this request we want to find out what's happening there also I want to highlight this if we pull up contrl F now we're searching for something let's backspace over this let's press the do asteris so we know we're using reg X and we can search for that uh back slash T lowercase T is what we actually want here and there we go so now you can see all of the tabs in this file it's all tab Del limited it doesn't look like they're the same spaces that but they are so this would import correct ly into a spreadsheet or something if you were making a text log file so that's what we wanted as well let's take a quick look at that employees controller just to see why we're not getting the context that we expect to get so here is this. logger.log request for all employees that looks fine let's come up to the top here private readon logger new my logger service and we're passing in the context here as well this tells me I might have something wrong in the log method itself for my logger let's go back and look at that we're in the my logger service now and let's take a look at what we're passing in when we log something here and I think I see my issue I'm only passing in a message to the log and it actually needs the context passed in as well so let's go back to that employees controller now and let's verify that so when we scroll down here and find where we're logging we're only passing in the message let's go ahead and pass in that context so the context was employees controller. name and now that should not be undefined in our log if we go ahead and have another issue so let's do that we've still got our server running go to our endpoints over here send another request for the roll pasta we send that in it's unprocessable that's fine but we did make a request right no this was the other issues so what we want to do maybe is make a get all request or maybe it actually logged both I think that's what's happening because it's logging when we're making the get all request route but it's also catching the validation error so let's see what we've got and now if we come down here that is exactly what's happening so before we had undefined and all exceptions filter with invalid but here we now have the employees controller and the all exceptions filter so we're getting the context of each so I just missed passing in that context with the log statement inside of the employees controller we're in the Prisma docs now I promised I would talk about all of the different Prisma errors and you see them here on the right under the error message reference you could look for all of these inside of that if else if statement and handle them accordingly to each error so we talked about the validation error but you could get other Prisma client errors as well like possi not connecting to the database for example things like that that could be handled here also and finally I want to highlight one package we did not use because it's not built into nestjs but it is a commonly used package from a third party here called nestjs Das Prisma and they just make the implementation when you're using Prisma fairly easy to do and so they've added some extra nice things we've got logging middleware and an exception filter here too that you could also look at how to do these same things with I just wanted to cover what was built into nestjs and with that we have completed a full rest API in njs now you should customize this make it your own especially when it comes to the data I just gave examples but this series should have been a good starting point for anyone getting started with nestjs not beginners to programming but again beginners to working with the nestjs framework that is built on top of nodejs and express remember to keep striving for Progress over Perfection and a little progress every day will go a very long way please give this video a like if it's helped you and thank you for watching and subscribing you're helping my channel grow have a great day and let's write more code together very soon
Info
Channel: Dave Gray
Views: 9,482
Rating: undefined out of 5
Keywords: nest.js, nestjs, nest.js tutorial, nestjs tutorial, nest.js rest api, nestjs rest api, cors, nestjs cors, nest.js cors, rate limiter, rate limits, nestjs rate limit, nest.js rate limit, server logs, nestjs server logs, nest.js server logs, logging, logger, nestjs logging, nest.js logging, nestjs logger, nest.js logger, exceptions filter, exception filter, nestjs exception filter, nest.js exception filter, nestjs prisma exceptions, prisma exceptions, all exceptions filter, js
Id: hQTtioSw4Zo
Channel Id: undefined
Length: 49min 44sec (2984 seconds)
Published: Fri Dec 08 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.