What is Express JS middleware and how does it work?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this video is part of the passport j/s user authentication series which in the description to this video I've linked the playlist to that video series but it can also be used on its own we're basically just going to be talking about what is Express middleware and how does it work on its most basic level the reason for this video is I think that when you start out using Express j/s as a framework it's an entirely middleware based framework but generally when you first learn it you're just copying in you know the different pieces and you know that there's kind of something working behind the scenes but you don't know exactly how it's working so in this video we're gonna talk about how exactly does this middleware work and how does the request/response and next or callback object as well as even the air object work in an Express application in order to do this we need to spin up a really quick basic application what I'm working in here again this is part of the passport j/s series so in the repository that we're using for that but don't worry this is just a basic Express app so we first need to require in Express I've already installed this with NPM so I don't need to do that and then we say app equals Express and then we just say app dot listen on port 3000 so right there is the most basic form of an Express server that you can spin up and if we were to visit localhost 3000 we're not gonna get anything but if we just throw in one simple route apt-get and then we pass in the request response and next objects and then we send some sort of data we can now run this in the browser so let's use node Mon which is going to automatically update on every time I save and we'll run a pas so we're running app DJ s it's listening on port 3000 and it'll be listening on localhost so if we go to the browser and visit localhost 3000 port 3000 you should see the hello world so we have a basic server running and that's all we need to do to start understanding how middleware works in express so we come back to the code here and the first thing that you need to understand is this right here so with our app get this is just a route that we've established in our Express application we are passing in a route string and a callback function usually you'll see it in this syntax but to better understand it we can just basically write a function where we say request response and next now to make this even more transparent what I'm gonna do is name these custom properties so normally you're gonna just see it our our eq r es for request and response and then next but you don't need to call them that it's just always gonna be passed in you can call them whatever you want so we can say request object response object and callback function so well actually probably shouldn't call it the callback function we should say maybe next middleware or something like that because the purpose of this last parameter is if we call it as a function it will pass it to the next middleware in the chain so we'll understand that a little bit better in a sec but first let's go ahead and write our function so we need to give it a function name so we'll just say standard Express callback and we pass in these three parameters and then we can say res send and hello world so basically we've got the same exact thing that we had below in the app get route to implement this let's just delete what we wrote here and let's just pass in our standard Express callback so we have to find it up here we know that Express as a framework is going to pass in these three parameters and so there we can just throw it into our route and click Save and then if we come to the browser again if we refresh the page it's gonna say res is not defined and the reason being is because I was dumb and forgot to update that so now that we're passing in request and response object we obviously need to also use that in the body of the function so that was just a silly mistake but now if we come to the browser and do it again we should get hello world as we expected so that's the most basic way that an Express route works and we're using this function that we had defined so just like we could define this function we can also define other functions which we call middleware so the way that we do that is pretty simple we'll just say middleware one and what we need to do is pass in those same three objects that we were using before so the request object response object in next middleware or whatever you want to call them in this case I'll just say require eqr yes and next like you would normally see it and then we can do whatever we want in this middleware so maybe we'll just say console dot log I am a middleware and then in this one this is the standard Express callback this is where we returned some data we can say console that log I in the standard Express function so if we just define that function up here and we don't do anything with it it's not going to do anything obviously but we can pass that into our route to make it work for us so let's pass in the middleware one and a comma so you can see that Express as a framework allows you to pass in pretty much as many parameters to the different route functions as you want let's go ahead and save this real quick let me open up the terminal a little bit more so that we can see what's going on and let's go to the browser and visit that same route we'll go ahead and click refresh here and you're gonna see that this is gonna just keep loading it's not going to ever return us data and if we were to you know copy this into a new tab and click enter it's not gonna actually return us anything and that brings up a very good point with express middleware if we come back to our code that we wrote you'll notice that in this middleware that we passed into our route that we were visiting we haven't actually called this next parameter so in the Express framework the next parameter is going to be actually a function and all we have to do is call it at the bottom of our middleware and what that's gonna do is it's gonna say for this route right here we first run middleware middleware number 1 or middleware 1 and in middleware 1 we call the next function that was passed in as a parameter by default by press and when we call that it's gonna basically say okay now we get to go to the next middleware or in this case it's the last one it's the standard Express callback so if we don't put that next to function and call it it's never gonna get to this last function and we're not going to ever return any data so now that we've called this next function we should be able to go back to the browser and see a response so if we refresh we'll see that it should return hello world and you see that it did return it and if we come back to our code again you'll see in the console that we printed I actually ran this route twice so we printed I am a middleware and then I am the standard Express function and the order of this is very important because first in the route we run this middleware and then we run the standard Express callback so first we're gonna console.log I am a middleware second we're gonna console.log I am an Express function so that is the basics of how this middleware works but we also have a few other things to understand so what we've been using so far bypassing the middleware into the route itself is a route specific middleware now this is kind of I just think of it this way I don't know if it's the exact term that you would use but I call this a route specific middleware but you also can have a global middleware so if I took this out of the route and I came up to the top right under the definition for the app and I say app got you use what this function built-in to Express expects is a function or a middleware that it can execute so in this case I'm going to just take middleware number one or middleware one and say app dot use middleware one so what's going to happen is the express app is going to initialize and then it's going to initialize the middleware one so let's go ahead and see what happens in the console when we do this so I'll let me make sure I got this right so we've got our middleware defined here we call next and we're initializing it with the app that I use up here so let's save that and you'll see that nothing has happened in the console yet you might expect since we did this outside of a route that it would just automatically print I am a middleware and go to the next something but that's not the case when we say app dot use it's basically just adding a piece to that chain of functions or middlewares that we're going to be calling so once again we have to come back to Google Chrome and execute this get route so let's enter and so it loads correctly and then if we come back to the code again now you're gonna see I am a middleware and I am the standard Express function so what just happened here well first off we defined that this is the first middleware that we want to use in all of our routes it's not just specific to this particular route it's going to happen in any route that we define within our application next we have the standard Express callback which is in this specific route so first the routes gonna call middleware one then it's gonna come call whatever we had defined as the callback to that route so the order of the middleware that we define and the scope whether it's a global or a route specific middleware really matters so let's go ahead and see what happens if we switch up the order of the middleware and maybe even add another middleware into this equation so let's say we have another middleware called middleware two and again we pass in the default objects that we are provided by or provided with by the Express framework and we'll say console dot log I in middleware number two and maybe we should just update this one up here to number one so we've got middle we're number one in middleware number two and what I'm gonna do is say app dot use middleware - okay so we are using two middlewares and then we have the standard Express callback which at this point I'm just gonna go ahead and put it in a form that we're used to seeing so we'll just use request res and next this is what you'll see in most tutorials so I want to keep it consistent so let's copy that in there delete the function declaration and then of course since we changed the name of the parameter we need to also change the name of the object that we're using to send the data alright so let's just quickly recap what we got we have one route in our application which has a very standard syntax all we're doing is we're sending back in h1 tag with hello world in it so far in this route we haven't defined any route specific middleware but we have defined global middleware so let's see what happens go ahead and kind of make your guess as to what's going to happen here but if I had to guess we're probably going to print a middleware number one and then I am middleware number two when we call that route and then finally we'll you know console that log I am the standard Express function alright so we've saved it let's go back to the browser click refresh and I don't know why it hangs sometimes here try it again maybe we have some sort of air did a little bit of refactoring nope it was doing just fine we've got all the things that we expected so if you could guess what's actually happening here is again we forgot to call the next function in the middleware - so it never reached this final function save it once more come to the browser once more and refresh we should get a good response come back to the code and you'll see I am middleware number one I am middleware number two and I am the standard Express function all right so everything is as expected and now is where the real you know understanding comes into play because often times when we're using an Express application we've got all sorts of middleware working together in most Express application x' you're gonna have several app dot use statements so you might say app dot use cores cross-origin resource sharing that's a pretty common one or app dot use body parser and then whatever the configuration for that was so you might have up to like 10 15 even 20 different middlewares that you are adding to your Express application and so it's really important to understand that the order that we put these in matters so if we were to put middleware one after middleware two all we did was change the order of those statements if we save and then go to the browser and call that route you're gonna notice that when we come back to the code we now have things out of order so we have I am middleware number two coming before number one so that's really important to understand and then of course if you put one of these within the route itself it affects the order as well so let's add one more middleware to this equation and it's just let's just copy this do the same thing so we'll call this one number three number three right there and then we're gonna take middleware number three and put it in the route itself so let's copy it right there give it a comma and now what's going to happen is we should have middleware two called first then middleware one then it goes into the route specific middleware so then we have middleware three and then finally this last function which we technically could call middleware as well so let's see if that worked we should have middleware to one then three so let's go to the browser run the route come back to our code and you see that we have two one and three exactly how we defined it to 1 and then the route specific middleware there are two more things that I want to talk about when covering the topic of Express middleware and one of those is air handling because an air handler in Express is also just another middleware but it's actually a special type of middleware so in order to define an air handling middleware what we have to do is define a function with a fourth parameter so let's go ahead and define a function called air and blur and you'll see that in this app I've kind of simplified it a little bit so we only have one middleware we got rid of all the rest of this stuff but this time we're going to pass in an air parameter then the request press in next parameters so this is how we define an air handling function and we can you know this is basically a middleware so we can do as many air handlers as we want so if we wanted to catch specific types of errors so we say if air that status equals something then we want to you know handle it in this one and then we could come down and do another air handler and say this is air handler number two and if air air dot status is number two number one you kind of get the point we can define as many of these as we want and handle different types of errors depending on the application that we're doing but what is going to happen here is this error parameter will be populated with an error if it exists so what we can do is we can say something like maybe instead of throwing the air explicitly we'll say if there's an air what we can do is res dot sin and we can say there was an air please try again so something more friendly than a default air that you would might you might get in the browser that would crash the entire application so let's go ahead and comment this out for one second and see what happens if we don't have an air handler so right now we don't have an air handler and maybe in this middle we're up here instead of console logging I am a middleware and continuing to the next we can say that we have an air object which is a new node.js air so I am an air and what we can do with this is we can pass it in the next function so normally we just call next and it goes to the next middleware this case we're gonna actually pass the air object so this would be common you know this would be more common in a scenario where maybe our middleware was doing something complex we were making a database call and we were just catching any airs that happened with the database something that we cannot control so we always want to catch these airs and if we do catch them we want to pass them in the next function so when we do that we're going to go back to the browser real quick and if we refresh this it's gonna say I am an air and you're gonna get the entire stack trace which you don't want because this is where the users will see what's going on and you obviously don't want to send this type of air to a user you want to handle it in a more graceful way and not to mention if we do it like this you can see down in the console or in the terminal that we've crashed our application so if this is running out on a server somewhere and we don't know that this has happened our application could be down for hours without us even knowing so it's really really important that we use an air handler in our Express application to catch these errors and handle them gracefully without crashing the Express application so again air handler just another middleware with one extra parameter so let's uncomment this air handler function and normally you'd set this up a little bit more complex than what I've done but we'll just go with this for now just to demonstrate the point so we've got the air handler and so now we're gonna say app dot use air handler now we'll go to the browser again will refresh and now we're getting a more friendly air message now that we've defined this air handler let's go ahead and put it in as a middleware so let's just say app dot use air handler and click Save now let's come back to the browser real quick and refresh you're gonna see this dreaded error message in the browser and you're gonna ask yourself why we defined our air handling middleware so we should have a friendly message here well what's happening is we have done this out of order and like I said earlier in this video the order that you put express middleware in matters and in this case we need to throw our air handler at the very end of our app so after all of our routes in all of our middleware we need to put our air handler and the reason being is because if there is an error in any of our middlewares or our routes which are basically just middlewares then the air is going to be passed directly to the final air handler so in this case we have the air happening up in our first middleware so what's going to happen when we say next and then air express is gonna pick up on this and say oh there's an air let's send it past you know let's skip the route here we don't need to go into this we need to just go straight to the air handler and handle it appropriately so this is kind of how Express middleware works and you can see that this will more gracefully handle the air if we come back to the browser and refresh now we're getting a much used more user friendly message in many cases you might do something instead of actually sending data like this we could just say res dot JSON and then we could say air and then our front-end application could handle this air on the front end rather than you know the server handling it all right so we have covered how to handle airs using air handling middleware and finally the last thing that I think is important to cover when it comes to Express middleware is the fact that we can actually mutate or kind of append different properties and objects and functions to these parameters that were passing through each of the middlewares so what we could do here is let's once again let's get rid of the air in this middleware let's also get rid of the console that log we just want to have a basic middleware let's call this number one again then let's say number two and let's put these in and global middlewares so here's middleware one and two so first our routes gonna call middleware one then two and then the actual callback for the route so to demonstrate this let's go ahead come up to middleware one and say something like request that custom property equals 100 all right so we just created a variable that is attached to the request object now since we're passing since express as a framework passes this request and response object through each of the middlewares it will actual be available to us in later middlewares so what we can do is we can say we define it up in middleware one then in middleware two we say console that log the custom property value is and then let's put in that custom property so in middleware number two we should print the custom property value is 100 but then we want to reassign it so let's say custom property equals 600 just a random number and then finally down in our routes we'll say the value is and then we'll put in request dot custom property and in this case it's probably going to print or not probably it will print 600 because we have modified the property in middleware number two so let's save that go to the browser and see what we get so we see we see that the value is 600 and that is because we set it in our second middleware which was the last middleware that modified that property now you might be asking what is the point of this why did you show me that well the reason being is because it helps you to understand how a lot of the middlewares that we use on a daily basis in express are actually working so if you're following along this series the passport j/s series for user authentication this is exactly how passport j/s which is an express middleware is going to keep track of users whether they're authenticated or not they the passport middleware is going to take that request object and it's going to actually append different properties to it and also if you watched the previous video in this series on the express sessions middleware you also know that the requests that session object is where the session is stored so you can see how powerful this is in how we can actually store data within the request object and you know each of our middlewares can have access to that data even if they come way after the middleware that first modified the data so that's just kind of a brief explainer of how middleware works in Express and how air handling middleware works in Xpress hopefully it kind of broadens your Express horizons a little bit I know when I first learned it it did and it made me a lot better Express developer I now write middleware for all of my applications to do just ad hoc things anywhere from you know authentication guards so maybe we're checking a value of a user that we've received maybe we're checking if they have administrative rights and we use a middleware to do that so the middleware would basically look up the user in the database check the admin property if the admin property is true then we pass it to the next middleware if it's false then we might return something like 401 or 403 unauthorized HTTP statuses and with that I think we are pretty much done with this video obviously there's a lot more to learn with Express middleware and entire frameworks and NPM modules are created based on this model but hopefully this basic explanation makes you a lot more powerful Express developer if you liked this video if it helped you out be sure to give it a like and subscribe
Info
Channel: Zach Gollwitzer
Views: 28,939
Rating: undefined out of 5
Keywords: passportjs, user authentication, nodejs user authentication, expressjs user authentication, passport local, passport jwt, javascript, express middleware, HTTP Cookies, HTTP Headers, express sessions
Id: AZDTM0DiLG8
Channel Id: undefined
Length: 30min 28sec (1828 seconds)
Published: Mon Feb 03 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.