This course has been updated! We now recommend you take the AWS for Front-End Engineers (ft. S3, Cloudfront & Route 53) course.
Transcript from the "The Web Server Code Demo" Lesson
[00:00:00]
>> [MUSIC]
[00:00:03]
>> Kevin Whinnery: For those of you who haven't maybe seen Express before, I'm just gonna do a very brief demo of some of the key things that you'll want to accomplish when you're building an Express application. So I'm just gonna do one from scratch to kind of demonstrate how Express works.
[00:00:23] And here in this directory, I've actually already downloaded the Express module, so I can write a simple node program that's going to use it. So I'm gonna create a new file, index.js, which is gonna be our simple Express application. I'm going to open that up.
>> Kevin Whinnery: And in my text editor here, I'm gonna be able to require the Express module.
[00:00:48] And I'm gonna repeat some things that if you've been doing node for a while, you probably already know. So I apologize for that, but there are lots of folks in the room and online whom some of this stuff might be new. So I'll break it down as best I can, and feel free to shoot in any questions that you have along the way.
[00:01:05] So the first thing I'm gonna hue is require Express as a common JS module. And this is the modularization mechanism provided natively in node JS.
>> Speaker 3: And if we could, in the text editor too, if we can bump [INAUDIBLE].
>> Kevin Whinnery: Sure thing, I could probably go a little bit bigger.
[00:01:34]
>> Kevin Whinnery: All right, so there is a global function in a node program called require. And when I pass into name, it's going to try to find a module of that name. So if it's just a string like this, like express, it's gonna reference the node module path. And the way that, that is resolved is in a couple of ways.
[00:01:54] First locally, here in this directory, if there's a node modules folder, it's going to look in here and say, there's something called Express in this node modules folder. So I'm gonna load that module from there. And after that, if it doesn't find Express in a local node modules folder, it'll actually start walking up the folders up above that, looking for node modules and failing that, it will look for globally installed node modules.
[00:02:23] So if you've installed express globally, it will require that version of the module. If you want to require local modules that you've created, which we'll do here in a second, there's a slightly different syntax for that. But now, I've created this express object which represents the express library.
[00:02:44] And I'm gonna create an application just using the Express constructor or the Express builder, I would say, it's not really a constructor function. And with that application, I can start defining routes to handle incoming HTTP peer requests or I can start configuring middleware. But before I do that, the Express module does have the capacity to start like a built in HTTP server which we'll do on port 3000, so that'll actually start listening for requests.
[00:03:21] Typically, you don't use the built in HTTP server like this, but for demonstration purposes, we'll do that. And there's a couple ways were I can define handlers in my application. And app.use is a way that I can define a middleware function for my application. So use expects a function as an argument.
[00:03:50] And a middleware function will have an area of three so it'll take three arguments which is going to be the request, your response, and next. And next is a callback function that is going to be called to continue on processing the request after the middleware has finished executing.
[00:04:11] So in this case, a common use case for a middleware is to check for an authenticated user, and then add that user's information to the current quest for downstream processing. So I could say, request user equals name Kevin or something like that. Maybe I would check the cookies associated with the request and get some data there.
[00:04:39] But I would do some processing on the request and or the response. And then whenever I'm done executing that logic, I'll just call next, and then the request will continue processing. And then when I want to handle specific, yes, question.
>> Speaker 4: Is there a meaningful difference between declaring your app variable and using a let versus a var?
[00:05:06]
>> Kevin Whinnery: The difference with let is block scope. It's actually the scope in which the variable is declared. So with var, the scope is always going to be whatever the enclosing meaning of this would be. So if this code were to execute in the browser, outside of a function scope, if I did var app, that would declare the app variable globally.
[00:05:30] Let declares variables within the scope of a block. So in this case, this method is visible to my entire application. But if it was declared within an if block or some other other kind of block within the application, it would only be scoped. It would only be visible within that block.
[00:05:49] So you can basically use it in place of var. And it usually means what you want it to mean which is declare this variable inside the current block scope. So in the const is for variables yet you don't expect to change, they should be immutable, essentially. So we create the application, we define some middleware.
[00:06:14] And then we can handle specific HTTP methods on the application as well. So when a browser makes a web request to our web application, that's an HTTP get request. So on our application object, I can say get, whenever there's a get request to slash hello in my web application, I want to execute some logic.
[00:06:38] And in this case, I'm just going to create a callback function with a request and a response. Technically, I don't even need these other parens but it's a hard habit to break, and I'm probably not ever going to use it. Never gonna to break it, I don't think.
[00:06:55] But at this point, I'm probably going to render an actual response to this route. So now, I'm gonna say response.send, and response.send will send back different content types depending on the kind of object that you pass it. If you pass it a string, it will assume that you're trying to send HTML back to the client.
[00:07:21] If you pass it, a JavaScript object, it'll serialize it to JSON, and assume you wanna send JSON back to the client. So in this case, I'm gonna send back a string that says, hello, request.user.name. And it's gonna use that value which was defined in the middleware to actually insert that name into the HTML response that I'm sending back.
[00:07:53] And this is another newish feature that I won't beat in, but it's possible to do string interpolation in this version of node using the back ticks rather than the single ticks. So it's just one of those niceties that is snuck into the language recently. So if I save that up and run the program.
[00:08:16] No, yeah, I'm actually already running something on port 3000. That would be why. Okay, so now, I have a little Express application running on port 3000. And if I Visit hello in the browser, I see Hello Kevin which is based on the result of that middleware stack that I defined.
[00:08:39] Now, the way and typically, if you as an application developer are creating your own middleware, you don't probably wanna define middleware in this way. Most of the middleware that you see, that you'll use from NPM or else we're on ecosystem, will actually define a constructor function which returns a function that you can use as middleware.
[00:09:05] So in this case, I'll just demonstrate that technique really quickly by creating a new file, we'll call it middleware.js.
>> Kevin Whinnery: And in this case, I'm gonna create a function that's going to accept some arguments, and then produce a middleware function as a response. So I'm gonna do a function called create.
[00:09:39] And it'll accept an argument like a user name. And this create function is itself going to return a function.
>> Kevin Whinnery: Which will be the actual middleware that's actually not necessary. So this will be the actual middleware function that you can mount in your application. So if we copy over kind of what we did here, we get request.user.name.
[00:10:16] So we put that processing logic inside of this middleware function, excuse me, let's do that. But now, instead of like hard coding the name that we send back, we'll just pass in the username that was configured here. And in this way, you can essentially parametrize the creation of your middleware, so you can have middleware behave differently based on the arguments that are passed.
[00:10:44] And so typically, this is how you're gonna wanna construct some middleware. And then to actually make that create function, the public interface by module, I will assign that function that I just created to module.exports. So now, I can require my own middleware by passing in a relative path to the module that I'd like to require.
[00:11:16] So in this case, it's gonna be in the same directory. It was called middleware. So I'm gonna require that middleware function. And now, rather than having the function inline there, I'm going to say,
>> Kevin Whinnery: Gonna change up my middle ware to pass in a different name. And now, if I kill that process and restart it, go back out to my server.
[00:11:47] I have a parametrized middleware that does something slightly different. So again, if you're developing your own middleware that's typically the way that you're gonna structure it with a factory function that will, in fact, return a function based on the parameters that you pass in. Any questions on Express or middleware right away before we keep trucking?
[00:12:13] Or things that you'd like further information on before we tried ourselves?