NestJs caching with Redis

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
why should you use a cache well the quick answer is improving your app's performance when a client makes a request to your server in this case our njs application in most cases we're going to fetch some data from our database and then return it as a response back to our client what happens when the number of clients increases that would mean a bigger load on our database and slower API response times one way of fixing this would be using a cache from one side accessing or retrieving data from a cache is faster than retrieving data from a database and that's because accessing data which exists in memory is faster than accessing data that exists on disk so that would mean faster API response times back to our client that's a happy client and on the other side we're also reducing the number of calls made to our database since now we're accessing it less frequently and we're using a cache so we end up with less load on our database and faster API response time leading us to saying that using a cache improves our application's performance now let's see how we can Implement caching in nestjs the first thing we need to do is install nestjs slash manager and cash manager packages cash manager is a nodejs cach module that allows us to interact with our cache so we can use a simple API to get data set data delete data from a cache and it also supports different cache stores such as redis for example to enable caching in our application we should import the cache module and then call the register method on it and the cache module comes from nestjs slash manager that we just installed and then if we take a look here we can see that we have many different properties that we can configure for example TTL or time to live is the amount of time that an item is stored in a cache before getting deleted by default it's 5 seconds then we have store by default it uses in memory store but later on in this video we're going to see how we can use redis instead we have Max which is the max items that can be stored in a cache at once and then we have is global which I'm going to set to True setting is global to True is going to allow us to use the caching functionalities everywhere in our application without having to import the cache module every single time after registering the cache module we can now use the cach manager provider to interact with our cach in our application to inject the cash manager provider as a dependency all we have to do is use the inject decorator from njs / common and then the token name is cach manager and then we call the variable cash manager which is of type cash which comes from the cash manager package now let's take a look at the different operations that we can do so we have delete get set and so on let's try to set an item in our cache we need to provide a key name so key1 let's say and then a value let's say hello and let's try to return this item so so using get and then we need to specify the key name which is key1 I'm calling that get students method from our students controller so/ students and then I have imported the students module in our app module so we can call this API if you go to postman and hit send as you can see we retriev the value hello correctly now to make things more interesting and realistic I have implemented this retrieve students from DB method which simulates a get operation from a database so what I'm doing is I'm setting a timeout and then after 1 second I am returning a list of students so our job here inside of our Asing get student method is to check whether or not this data is stored inside of our cache if that's the case we return it right away from the cache itself without having to call our database if not we would need to get the response from our database and then store it in our cache for future use so let's see how we can do that first thing we need to do is check if we have the data cached so in our cache manager we use the get operation and we use the students key to check if we have any cached students data if that's the case then we return it right away and here I set a log got data from cache and then in case we don't have the data cach then we would need to call this method as such and now we would need to store it in our cache before returning it that way next time we make this API call we're going to get the data from the cache and not from the database so just like we've seen before I used the set operation on our cache manager to set an item in our cache I used the students key and then added the students data as a value and then I returned it now before making an API call and testing this out I'm going to override the default TTL which is 5 Seconds I'm going to set it to 30 seconds here it takes a number in millisecond so 30 * 1,000 now this is 30 seconds meaning our items will be stored for 30 seconds in our cach and then they will be deleted so let's go to postman if you hit send as you can see the response time was over 1 second we got the data here if we take a look at our logs it did not say got data from our cache so it did retrieve it from the database however now if I hit send again as you can see it only took 5 milliseconds and if you take a look in our log we can see got data from Cache so the first time we didn't have anything our cach we had to retrieve the students from our database after doing so we have stored and saved the students data inside of our cach for future use and as you can see fetching data from a cache is very quick it only took 5 millisecond to get that data now let's say you wanted to use a TTL of 30 seconds in your application but in certain cases you wanted to overwrite that value you can do that so whenever you are setting a new item in your cache you have a third optional parameter which is TTL so here for example we could specify that for this item we want to set the TTL to 60 seconds so this item would be deleted after 60 seconds instead of 30 seconds thankfully we don't have to write this logic every single time because nextjs provides an automatic way of actually caching results and then retrieving them but before get into that please make sure to leave a like And subscribe n provides us with a cache Interceptor that does that job for us so here if you say use interceptors just like with any Interceptor it's called cache Interceptor and it's from DJs /h manager package just like any Interceptor it could be on the controller level or it could be on a route Handler level or it could even be globally for our whole application in this case we just want it to be on the controller level also it's important to know that this cache Interceptor only works with get route handlers so anytime we have the get method it doesn't work on postp putut and so on now since this cache Interceptor does that logic for us it checks if we have some cache data with the specified key and then if that's not the case it goes inside of our service and does the logic and get the data from our database and then it saves the response for future use we no longer need to have this logic manually we could just call retrieve students from DB and then here let's add a log inside service and I'm also going to add this log here inside control now let's see what happens when we call this API if I hit send as you can see it took around 1 second and then if you take a look at our logs we can see inside controller and inside service meaning that the cache Interceptor didn't find anything in our cash so it continued to our controller route Handler and then the service here now if we hit send again as you can see this time it only took 4 millisecond let's hit send again again again as you can see it's very quick now 2 milliseconds if you go back here to our logs we are not entering our controller and service anymore so the cache Interceptor is fetching the students response from our cache and then returning it now for example the 30 seconds have passed which is the TTL that we set if we hit send again as you can see once again it's 1 second but if you had to send again it's 2 millisecond now so the cache Interceptor is working perfectly just like we've seen before we can overwrite this TTL over here this time by using a decorator so at cach TTL and then here we could specify for example 60 * 1,000 meaning 60 seconds so the items here or the response from gut students that is going to get cached by the cache Interceptor will be deleted after 60 seconds it's important to know that if you decide to use ATR here to handle the response manually this would not work properly with the cache Interceptor so that's just a side note and now the moment you've all been waiting for let's see how we can use redis as our Cache Store the first step is to install cach manager redis yet now we need to import Reddit store from cach manager reddis yet and we can use the store property that we've seen previously and then pass in the Redd store as a value if you take a look at Redd store it's a function that takes some options red clients and then it returns a promise of red store now by default if you just pass the red store to the store property it's going to connect to a local redis server so Local Host and then the default Port that redis uses in my my case I have a redis image from the official redis and then I am running this as a container so I have a local reddis server here if I open the CLI red- CLI if I hit ping as you can see it replied with pong so I'm connected to a local Reddit server you can do the same you can get doer desktop and then run a redis container or if you're on uh Mac or Linux you can actually get the red server so we just follow a simple tutorial online and get ready now to visualize the data inside of our reddis cache I installed a software called Radice Insight you can think of it just like mongodb Compass is just a data visualizer for mongodb this is the same for redis so here we can see what keys we have and so on thankfully and if you remember I previously said that with cash manager we can switch stores without actually having to change anything so it provided us with a simple API that works with any uh store so now we don't really need to change anything in our code and to verify that if we hit send it took 1 second if you take a look here inside controller inside service if you open red this insight and refresh as you can see we got an item here and as you can see here we have a time to live which is 52 second now if I refresh 46 45 and then we have a key name here which is/ student now previously whenever we used the cache manager whenever we injected it in our service here we used cach manager. set and then we set the key manually however now the cache Interceptor is the one caching our data so as you can see by default it used the route path as a key name also if you take a look at the value here we can see that it saved our data as a string in this case so the type here is string the key is students and then the value is the students data that we are getting from our get database function now if we refresh the item is no longer here it got deleted and that's because the 60-second time to live was up so it got deleted from our cache so as you can see everything we said everything we worked on is working perfectly now let's say for any reason and this is rarely the case but let's say for any reason you didn't want to set a time to live you wanted it to stay forever in the cache you would use zero if I hit save and restart now it will take take effect with the cache Interceptor now if you take a look at Red Insight we don't have anything here it's empty if I hit send here it took one second because we don't have anything cached yet if we refresh our cach here as you can see we got the item key SL students and then here we have our data but this time if we focus on time to live it's no limit and that's because because we set the time to L value to zero meaning Infinity now let's say you didn't want the cache Interceptor to set the key for you so we don't want it to use the route as a key here you can overwrite that just like we did with cach TTL we can say cache and then here key let's call it for example my key hit send it got cached if you refresh here we can see we got a second item called my key the first item didn't get deleted because the time to live is zero and we did not delete it manually and the second item is the one that got cached right now which is with the key my key and then has the value of course now if we hit send again it's going to fetch the response quickly and that's because it's coming from our redest cache this time my key of course if for any reason you didn't or couldn't use the cache Interceptor in your use case and you had to have manual control over your cache you can still like we previous seen inject the cash manager as a dependency using the token name cash manager and then here just like we've seen we have delete to delete an item you specify the key we have reset to empty the whole cache delete all the items and you can use get and set so you can still use this for any use case you need now of course this is fine if you're playing around or testing a few things locally however for production of course you would need to configure that redit store to connect to a red server on production so you would need to pass in a username a password the host and so on so to do that we would need to use the config service and of course to safely have your credentials you would need to store them in a EnV file now if you're not very familiar with those terms please you should go back and watch my episode on configuration in njs but let's do that right now in case you haven't seen this or you haven't worked with config modules before basically you install the njsc config which will allow you to register a config module using the full root method and then here we can pass in some configuration I passed or I loaded a config file this config file returns or holds the redus information here so for example host and Port of course these are not going to be hardcoded so let's go ahead and create a EnV file and then here we're going to set those and of course this EnV file should be added to get ignore so you shouldn't Commit This at all this should be secure and now here we use process. EnV and then the key name that exists in our environment variable to read those values and store them in our config file here and then in app module we are loading this config file and then I'm setting it to Global so that you can use this config service anywhere of course the config service is provided because we have injected the config module here in our app module now we need to use that config service to read and get the values from the red host and Port dynamically and use them in our store here instead of the default ones to do that we can replace register by register async and if you're not very familiar with register async and use Factory and inject uh please go back and watch a few of my episodes such as the mongodb or the config service I'm pretty sure we've mentioned this many times now but basically here uh we are injecting the config servers to be used as a dependency in our use Factory method so here we could say const store and then initialize that using redis store that we imported previously from cach manager redis yet but this time we are going to set the values so here for example we could say socket host which was optional because by default it's Local Host but now we're going to read it from this so config dogat and then rus. host and of course it's R host because here that's how it's nested and now here we need to return the store and any other options that could be returned from register so we could simply just say return store now I just realized I didn't add the import array here and import the config module to use the config service but that wouldn't cause any issues because we have set the config module here as Global now here we can also return different prop other than the store such as TTL Max and is global those are the same properties that we've seen with register previously however I found an issue uh this is something I didn't know about until I was filming this video so previously you remember that we said that the TTL property is optional and by default it's set to 5 seconds so in our cache whenever we save a new item it will take 5 seconds until it's deleted whenever we're using register async this doesn't take effect anymore I'm not sure why I haven't really looked into it but if you need to set a TTL whenever you're using the register asnc set it here inside of the Redd store properties that's pretty much it guys if you found this video helpful please leave a like subscribe and I will see you next time
Info
Channel: Computerix
Views: 924
Rating: undefined out of 5
Keywords: nestjs, redis, caching
Id: VD9XMGJQaT8
Channel Id: undefined
Length: 18min 17sec (1097 seconds)
Published: Sun Jan 21 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.