Decouple your NestJS code with this technique!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey how's it going I got a quick video for you today so I wanted to show you how to utilize event emitters to help decouple your code and this is a pattern that you can use in really any node.js app but I'm going to show you how to do it in Nash JS specifically so I have a simple Nest dress application here I'll walk you through what I have here so far so I just have a root app module you can see that I have a controller and two providers the controller is exposing a a post HTTP post route video which triggers video service dot publish you can kind of Imagine This sort of like if we were building the API for YouTube itself right when I publish a video I want to notify you guys to subscribers so you can see that we have some mock code here of us publishing a video with a specific title and then we want to trigger a notification to all of the subscribers right so in the viewer source that notify all that's doing is also logging out some code now right right now we don't have much here we publish and we notify and it's pretty simple however think of a scenario where you start to have more requirements to other things you want to do after a video is published or during its publishing right so for example besides notifying the viewers maybe we want to email the content moderators maybe something needs to happen to enable ads on the video and you can kind of imagine how this code will just keep growing as we have more and more requirements to happen upon publishing a new video and you can see how you start to create this uh coupling of dependencies because for example here in order for the publish method to call video server set Notifier right it needs to add this dependency and From nest.js's perspective if this was in a different module right it'll need to add it to the provider's array and that's going to have to happen for every single one of these like imagine these were all coming from different modules different Services all of those modules needs to become a dependency of the module that contains video service right so I hope you can kind of Imagine where the coupling starts to happen where the video service needs to be aware of all these other things and similarly all the people that are developing these other methods needs to know that oh they need to add it in this specific publish method and they also need to make sure that they don't break anything in here as they're adding more code right so I hope you sort of understand the high level problem that we're trying to solve is really we need to reduce the coupling between all of these and the publish method and a simple solution to this problem is that instead of us calling these things directly what we're inside gonna do is we're just going to emit an event that says hey I published video and the rest of our services are going to subscribe to that event so that they can do their own work separately in a different part of the code base so the way we're going to accomplish that is we're going to install the nest.js event emitter package now just to give you some quick context on what that package is it's really just a light wrapper to the event emitter 2 package which what that is is an implementation of the internal event emitter that you can find in node.js itself the core difference is that it's supposed to be more performant but basically if you're trying to further understand how this all works I recommend looking at the event emitter package documentation and then also using the internal node.js event emitter documentation there's also some good information there because again this is an implementation of that anyways after you do install the nest.js event emitter we are going to go into the app module and add that as an import here so make sure to add event emitter module.4 root from the nsgs event emitter let's quickly run our application just to see how it performs today without the changes so you can see that once our application is running if we do a post request to localhost 3000 slash video hit send you should see a response all done so in a terminal you should see those logs publishing a new video and notifying subscribers so at this point what we need to do is basically refactor our code to start using event emitters so instead of us calling the viewer service directly we are instead going to add the event emitter which allows us to delete all the code that was in here before and we can simply do this that event emitter that emit video dot created you can also pass in some kind of payload if you need to pass some kind of dto from your publisher to your subscribers so for example let's maybe pass in our Title Here we can then switch over to our viewer service and we're going to turn this into something that listens for those events so we're gonna do on event from messages event emitter and we're going to pass it in the same string that we're listening to so we're going to do video dot created remember we're emitting video that created with an object like this so that means we should also turn this into some kind of payload with a string title and at this point we should be able to go back to our request let's do another send here and you can see that we pretty much have the exact same result as before where we're logging publishing a new video from publish eventually it gets to notify and it's logging this part which is notifying subscribers now earlier we talked about how in this published code we had to you know call a bunch of functions we no longer need to do that if we were for example needed to do something else besides just notifying subscribers you can instead add another listener that has the exact same event as this one so as just another example let's say that we had do something here and we again added another on event here of the same event right let's just add another simple log here let's do another send on our publish and you can see that it just added in here and one important thing to understand here is that when you emit events like this it's not necessarily asynchronous it's actually synchronous by default even though they're events you might think of them as a synchronous but this is really equivalent to you know imagine we had an array of registered event handlers for this specific event right and it's really just going through that array and taking each function and just calling that right so that's really what's happening here that's the mental model that you need to have where really things are going to get executed in the same order that those handlers are registered right so in our code here you can see that this is logging out first and this is logging out second right so for example let's add one and two here just so you can see it clearly when I hit send you can see that it's publishing a video and then one two right so it's running in the order that is registered if I reverse these like if I just move the code down like this you can see that now it should do one and by the way if it helps understand this a little bit better here's the docs from the node.js site itself where they say if any mirror calls listeners synchronously in order in which they were registered it ensures that proper sequencing of events helps avoid race conditions and logic errors if you did want to switch that to be in a synchronous mode you can use set immediate or process that next sick methods within the handlers now for the event emitter package specifically you can see that they're emitter.on actually takes an options object and one of the options you can pass in there is async which says invoke a listener in async mode using set immediate so it basically kind of does that for you and where you can pass these options is within this decorator itself so you can pass an object in here for example you can do async true and that effectively is equivalent to wrapping this call in set immediate so make sure to check the official docs here to understand what are the different options that you can enable now one last thing that I wanted to quickly show notice that when we do this type of calling you sort of disconnect the the publisher to the subscribers but what happens if the publisher also needs information from the subscribers like imagine if we had something to return in here like let's return uh let's just do a number right turn one and return two what if I want to get back these values in our dispatch here what you can do is switch this to Emit async and you can see that this returns a promise so we need to take this publish method and turn it into an async and we're going to await the result of this now what you should expect this result to be is that imagine that this code that we had here before if we were to switch this to a map right so for each Handler we're gonna we're gonna call the function that is underneath that Handler and it's gonna this is gonna return something and then imagine that we wrap this in a promise.all right so because we're mapping we're getting back an array of all the things that this returned and that effectively is what we're getting back in our result so let's go ahead and log our result let's call our video right again hit send and you can see that we did one two and then we got back an array of one and two right again that's if you publisher need something back from the subscribers that's sort of how you can communicate back to the publisher Now One Last Thing Before we end this video one thing that you lose when you're simply emitting events like this is you kind of lose a little bit of the uh intellisense right like for example how do we know that the payload is of the shape if it's if anything can be passed in here right and what I suggest doing is creating classes to represent those payloads so for example maybe let's create a new file and let's call this video created that event.ts and that could just be a simple class of same name video created event right so let's do title string and it might be useful to add a simple Constructor let's do the set title equals title and I have a small typo actually here this should be video created event all right and now we should be able to go to our emit code and we can switch this to be new video created event pass in the title right so look like that then we can just go to our subscribers and replace these to the video created event and if we test our code one more time it should behave exactly like before anyways there you go there's event emitters for you in Nestle yes again you can also use this in Express or any node.js application and it is important to understand that this is just a simple way to decouple things there are other event based mechanisms where you know perhaps you can publish to a queue in AWS or you can also do Pub sub with things like redis right let me know if you want to see videos about that but anyways hopefully you got something out of this video and hopefully it's useful to you let me know what you think in the comments and I'll see you in the next video thanks for watching
Info
Channel: Marius Espejo
Views: 26,776
Rating: undefined out of 5
Keywords: eventemitter, event emitter, nestjs events, nest events, node events, nodejs events, nodejs event emitter, nodejs eventemitter, express js event, express events, event emit
Id: -MlXwb42nKo
Channel Id: undefined
Length: 11min 37sec (697 seconds)
Published: Tue Jun 20 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.