Loading
Lesson 07
Courses / Software School
Introduction to Express.js - Software School (2024-03-14)

Learn how to build an HTTP web server in the Nodejs (Serverside Javascript) programming language with the ExpressJS library.

The lesson goes over generating an NPM project and installing express.

Then, you learn how to code a basic server running at a specific port on localhost.

You learn how to define endpoint routes and their handler functions.

You get exposed to the browser developer tools (DevTools) to monitor network requests so you can understand the request-response from the HTTP GET request made to the web server.

You also learn how to send back HTML to the client.

You learn how to change the status code of the response.

The lesson also shows how to use the static files middleware so you don't have to manually define a route for every asset file that you might have.

The lecture also briefly shows how to send back a JSON response to the client.

Video Transcript

Okay, so today I'll talk about Express. Express. Yes. So this is the website for Express. Going back to Node here. So today if you have web development, right, you have HTML, CSS, JavaScript for the front end, and you can make like a website that's kind of interactive at some JavaScript, yes, it's very pretty with CSS. But you know, where does that, all that data goes? How is it stored? You know, it's stored in the database somewhere in what is called the back end. But the back end is a program to act as an intermediate between the browser, the client, the people accessing the website or web app, and the data. And that program can be built in any programming language today pretty much. So different companies use different languages for the back end server. A very popular choice today is writing a back end in the JavaScript programming language, which is the same as the front end. Traditionally, that was not possible, but it has been made possible with the advent of Node.js. Node.js put simply is just JavaScript, but on the server side. JavaScript, the language originated from client-side programming in the browser. And then somebody had the idea, okay, why not use that for other things outside the browser? So they created Node.js. Okay, so pretty much server-side JavaScript. So if you can write client-side, you can write server-side the same way, the same language. Now, writing that like a web server to serve pages or requests from users might be a tedious task if written in the very raw or lower level HTTP module from the Node.js. So express this library was written, and pretty much it makes it easier for us to build a web server with Node.js programming language. Okay, instead of us having to type everything from scratch, it already wrote the code for us, somebody wrote the code for us, and put it in a package that's called express.js. And that's what we're going to see today. Okay, so to get started, I need to go to the terminal. So let me share my terminal. Now, just go anywhere in your computer in your terminal, and we're going to make a directory for this project. I'm going to use the command MKDIR. Space, and then I'm going to call the director using dash express. You can call it anything you want. This is my name, but you can choose whatever. Press Enter, and the director is now created. If I say DIR to list, I can see it here. If here is in Linux or Mac, the command to list files is LS. The MKDIR should be the same across systems. Okay, I'm going to CD space using express to change directory to using express directory. So I'm in the right place. Now, since you installed Node, you should also have NPM, the Node Package Manager. So I can say NPM space init. And the reason I do this is so it creates a file called package.js.on, Jason. That would be necessary for us to define this as a Node project, and therefore we can install third-party dependencies, that is code that's written by somebody else. In this case, we're going to install the express library. So you can type, it's going to ask you a few questions about the content of the package.js.on file. You can just press Enter and accept the default. If you want to change, you can always change it later. Enter, enter, enter, enter, enter until is this okay? I'm going to say yes. Okay, now if I do the IR or LS in other systems, I can see there's a file that was created called package.js.on. Now you can open your favorite text editor on this specific directory that we created for the project. For example, I have Visual Studio Code, I could say code.spac..meaning current directory. So it will open my thing there. Since I already have it open, I'm going to just share here. There you go. This is using express. Actually, I should do code.there so it becomes just this here. So I don't have that thing intermediate. There you go. So we got this file that was created by NPM init called package.js.on. So we defined this directory as a node or NPM project. And we have several properties and values regarding metadata for the project. We don't really care about these right now. So just make sure it's there. Now going back to the terminal, we're going to install express. Let me go back here. I'm going to say NPM space install space express expr ess. It might take a while. Okay, so what this does is NPM is a node package manager. So it has a registry of third party software and you can pull that code from the registry with the NPM install command. Basically, if you have code that you wrote and you want to publish that as a package, you can publish that to NPM. And then people can download your code, use the NPM install. So when that happens, what it does is it creates a directory called node underscore modules and places all the third party code there. If I show you in Visual Studio, you can see now that the node modules directory was created. And if I expand that, there's a lot of packages. And the one we installed was express. You can see there's a directory for express. You can see the source code for express is here. Now the reason there are other folders inside node modules is because express itself, if you click on the package JSON there, depends on other packages, a lot of other packages. So it also has to download all of that, those other third party code and put it here. Okay. And there you go. If you click package.json, we should now see a property called dependencies and express is now included there. And what this means is our project depends on the express package. And the version we are dependent upon is this one, 4.18.3. Don't worry about this thing yet. Somebody asked, yes, what are the commands? So let me share again my terminal. I'm going to scroll up here. So I started off by creating a directory that I called using dash express with the mkidir command. Then after creating that directory, I want to change directory or CD command to that new directory I called using dash express. Within that directory, I call the command npm space init to initialize this directory as an npm project. In other words, it's just going to create a file called package.json based on the answers you give to the prompt. In this case, I just press enter all the way. I don't really care about answering them right now. You can always change that information later as I showed you there's a package that json file generated. After doing that, we can simply say npm install and then express everything separated by a space. Sorry, npm doesn't get recognized in my command prompt. Did you install Node.js? Is it Node.js I'm installing or the express? So let me share this browser here. Sorry, the JS I'm installing, I guess I'm using the Windows. This is the website for Node.js. If you don't have Node.js, you should install it. For example, click LTS version. And when you install Node.js, it comes with npm. Did you install Node.js yet? No, not yet. Okay, that's in progress. Yeah, make sure to install just click here open a wizard MSI, whatever. Okay, thanks. After that is installed, you will get access to Node and npm. Thomas asks, how do you know if express or any models are installed? I showed you that right so going back here to visual studio code. When you install any package for npm, it will install it under Node modules. So if you verify package.json, you should see under dependencies property, an entry for express, you see express here and the version that was installed. And another way of confirming if the file is there, go to node modules, and then verify there's a folder called express here. You see there's express here. So that means it's been installed. Okay, I'm going to go here and create a new file. Let's call this server.js. So under our directory using express, I created a new file called server.js. This is where I will write the JavaScript or Node.js code. Let's start off. It's a bit the boilerplate at first. So to require the Node module we installed, or library or package, you can say require and call it as a function, parentheses, and then under quotes, either single or double doesn't matter. The name of the Node package, in this case express. This has to match the same thing as the package.json dependencies, entry. Okay, and then we can place this in a variable. I will call it simply the same name as the module. Once we got that express variable, you can call it as a function, and that will return to you an instance of what we call app. You can start out in a variable, typically we say app or app. And finally, you can call, there's a function listen on this app object. So app is an object, so you can say dot to access an attribute or a method that is a function that belongs to this object. That's called listen and call it as like this. And then it was, you need to give it a port. So we can say 3000, that's the typical port we use when we start off. Okay, so that's the very basic server. Allow, let me explain again. So we installed express, which is a code code that somebody else wrote. So we downloaded that with npm. And to be able to use that in your own code base, we do require with the name of the module there. We take that and put in a variable. Usually I use the same name as the module for the variable. And then we call this express function to get an app object. And that app object can call the listen function with a port that the server will be running. Okay, so now I'm going to go, actually I can open a terminal from Visual Studio Code, so I don't have to change all the time. So I'm going to click, press control to back tick, or you can, if you use Visual Studio Code, it's terminal here. So I can choose, this one is just a power show, I can use different things if you use Visual Studio Code. For example, use command prompt. So I have a command prompt tab here. So I can type commands here as well. So I'm going to say node space server.js. So I make sure I'm in the same project directory as the file, the server. So I press enter. I'm not going to see anything, but it's actually running. Let me confirm using the browser. I'm going to go to local host colon 3000. Yeah, so if I see cannot get slash, I mean it's working. Let me make a bigger. Okay, so how's everybody doing? Yeah, so I went to my terminal, I type node space server.js. That's the file name for this that I wrote and enter. So it runs the program. Now you're not going to see anything. You're just going to see empty blank without the command prompt. You see there's no prompt here. It's just blank. It's actually running the server. So it's listening, right, to requests. So the address here that you have to go to is localhost colon the port that you specified on line five. In this case, the port of 3000. So I have to go to let me make a comment here. HTTP colon slash slash localhost colon 3000. Now localhost is usually an alias for 127.0.0.1 IP like the local. Okay, so if the local host doesn't work for you, try 127.0.0.1. And you got to add the port there. Okay. All right, somebody just joined. We're doing express. So we created a node project with npm in it and we installed express with npm install express. And we wrote this file server.js and we ran it in the terminal with node space server.js. Now this is like you said, what's going on here. I don't see anything. So that's pretty bad for us to understand what's going on. So we need some feedback. That's why we can add as a second argument to listen a callback function. Let's add function here. I'll write function keyword. And this callback function will be called as soon as this app or server initiates or starts listening. And we're going to say to the console a message. So I'm going to say console dot log parentheses. And we're going to say server is listening. So we have some feedback at HTTP colon slash slash local host colon 3000. Okay, so save that. Now when I change code, whenever I change my code, I have to go to the terminal, kill my server and restart our rounded program again. We always have to do that. It's kind of tedious. So to kill the server control C, when you say control C, it sends the interrupt signal and it knows how to stop. Once we do that, simply run the command again, node server dot j s, and that was started. Now we can see there's servers listening at local host 3000. Now I understand. Oh, okay, that makes sense. Now we have some feedback. We know what's going on. And you can even control and click this URL here. It will open the browser for you when you have URLs in the log here in the terminal. Hold control and click to follow the link. Now one thing, if you change the port here, this is going to be wrong, right? So you have to change it here and here. So if you want, you can create a variable like say const board equals 3000 and put a variable here instead of 3000. And you can also put it here if you interpolate the string like dollar. Worked. This is string interpolation, meaning the value of the variable port, which is 3000 gets replaced, whatever this is that. So it becomes like that. But in order to use interpolation, the quotes surrounding it must be a back tick. The back tick key is the one where the tilde is next to the one on a US keyboard. So back tick there and back tick here instead of single quotes. That's the only way we can interpolate JavaScript. And that's just so if you change the port here to whatever 4000, it will also change here and there automatically. So you don't have to write it twice. Now because I changed my code, I always have to go to the terminal control C to interrupt and then run it again. So it runs the new code. There's no change, right? We just did some variable no, no different from before. Now let's talk about the first endpoint. So, so what we have here typically a website will ask for information about specific resource. And that's usually done via what's called HTTP request, hypertext transfer protocol request. And for example, you want to you are in a store, like Amazon or whatever, you need to get the list of products, right? So get slash products. That's one endpoint or route for the request. Maybe want to get the orders to get slash orders and so on. So you can have many different kinds of requests, right, for a resource and those we can call endpoints or routes in our server. So let's create the route for the route, which is slash, right? If you go to our server, local host 3000, right, like I said, like I did in the browser. That's the slash, right? There's a imagine there's a slash here. That's the route endpoint, the route route. So how can we respond to that? So here before you have your listen and be and after the definition of app, we're going to say app, I'm going to say dot get, because it's a get request. In HTTP, there are different kinds of requests. Most popular is get and post when they say gets usually for obtaining some kind of information. So this function, we call it like that. And then you have to give it a path to this endpoint. In this case, just the roots. I just want to use the type local host 3000 like that in the browser, and it will go to the root. Imagine there's a slash there. Okay, so this is the root. So the second argument is a function that takes two arguments. The first is what we call our RQ or request. The second is RES or response. We usually write it like them very abbreviated, but you can, you can change the names if you want, but know that the first one is request. The second is response. Now they find that function. And what's going to happen is as soon as the user makes a request for a server, that is they do get HTTP colon slash slash local host colon 3000. It goes to this route. Route. So it calls this function here. This function will define these structures to how to respond to that request. So you can do whatever you want and then reply with some response back to the client. Now let's just say the message Hello world. So you're going to use the rest object that's provided here as a parameter. And it has many methods or functions. One of them is send. So you can send back information to the client. And the argument can be just a string. You can say Hello world. So what this does, okay, somebody went to localhost 3000 slash get request, and then we're going to send back a response send this string Hello world. And they're going to see in the browser Hello world. Once we save that, make sure to go back to the terminal control C to interrupt. And then you're going to run the code again. Now I'm going to go to the browser to show you what happens. See I'm in localhost 3000. That's the route route. If I click refresh, you can now see Hello world. What are you having trouble with Tiffany? Let me show you the code again so you can compare. We wrote this part. Did you write it like that? So what are you not seeing? Did you go to the, did you restart control C here in the terminal? And restart the app and then go to the browser and go to localhost colon 3000. Did you see Hello world there? Okay, then we can go on. Okay, yeah, make sure to spell everything exactly as it's written here because in programming, every character matters. The case matters if it's uppercase or lowercase. So make sure to look at every single character. Okay. All right, so that's nice. Now let me show you a way to debug requests. Let me share the browser here. Okay, if you want to know more about HTTP, I'm not talking a lot about HTTP because I assume you know some basic knowledge. You go to the browser and it makes a request. If you want to look part to that, you can search on your own HTTP if you want to know about the protocol. But basically it's just a request and you got a response. The client, the browser makes a request and then the server, in this case the express one sends back a response and the protocol is HTTP. So I'm going to go to the browser, open the dev tools with F12 or you can right click and inspect anywhere. I'm using Firefox. You might be using a Chromium based browser, but it's pretty much the same thing. Some labels might be different. Okay. So I'm going to go to the network tab. I think it's the same as Chromium, the same label. And I'm going to scroll up a little bit so I can see it better. I'm going to click to reload the page so I can see the request here. Make sure it's select all so you can see all of them. Otherwise there's a filter. So I click all here to see all the requests. Okay, so I can see there's one request here to local host 3000 and the method is get. You can see that here. See the slash. That's the root and it's a document. I can click that to see my information about the request and the response. So you can see here, scroll up a little bit. We have response headers. We have request headers. We have the endpoint here, meaning that what's the method is it gets is it post. In this case it's get and then the URL or address or whatever way you think of this. Typically it's called a link if you're in the web site. It's this localhost 3000 slash, which is the root endpoint or route. And it tells you what version HP it used and so on, all this stuff. You don't need to worry about understanding any of this. I just want to point out that this is the way of debugging your request to understand the request and response. So HP has headers that contain information about the request of response. You can see them here, response headers. So request is what we made, right? The browser, the client makes a request to the server. So the request headers were all this stuff and the response was all this stuff. So action information. As you can see, there's even a header saying export by express to let the client know, okay, our response was handled at the express library. And you can see other stuff that's we're not going to really talk about cookies or whatever. But if you click request, you can show you the payload if there's any in this case this request is get and there's nothing to provide the server. So there's nothing here, but the server does have a response with some text so we can see response. And it shows us Hello World. And you can click raw here to see the raw text. It's probably converted to HTML, but it's not HTML. If you go back to headers, an important one for the response would be the content type, but we don't have any because we're not sending HTML nor JSON as we're going to learn later. Okay, so that's the DevTools. Now, and close that and we can go back to the code. You might be tired of restarting the server. So I'm going to teach you a trick to not having to do that anymore. And that's called with a package called Nodemon. So I'm going to kill my server here, going to say npm space install space Nodemon. But the thing I'm going to do before the package name, I'm going to say dash dash save dash dev. Enter. And we're going to verify package.json. Now it's not under dependencies. Now it's under dev dependencies. And I see Nodemon and the version that was installed. And can also verify Node modules. There's a folder for Nodemon here. You can see that. Now Nodemon is a package. What it does is a little program that when you run, it runs your node code and then it will restart whenever you change the code. And that restart is automatic. So why use that? Because you can find a tedious, right? Every time I change my code, I got a patrol C to kill the server and then run it again. And I can forget, you know, I don't want to do that anymore. So let the program do it for me. So Nodemon does that job for us. Now, instead of saying node here, I'm going to say in PX, space, Nodemon and then server.js. And if you notice, I didn't say NPM install without save dev. And that's because I like to differentiate between libraries that are needed for production and for development. Nodemon is just a tool we use to develop. But in the actual program, when it runs in production to everybody, right, it's not going to be necessary because I only run the program once. So I'm going to use the node command for that. Nodemon is not supposed to be in production. That's why I strictly want to separate into a different category of dependency to be a development or dev dependency here. So if you add dash dash save dev, all it does is instead of placing Nodemon here under dependencies in the package.json, it will place it under a separate category. Okay. You don't have to do that, but I like to do that just to separate my kind of packages. One is just meant for development while the other is going to be needed for production. Yeah. You don't want to run Nodemon in production. Imagine if the code changes suddenly everybody's, the server restarted, keeps restarting. We don't want to do that. You just want to run it once with the node command. Okay, I'm going to do that. Now, why did I use NPX? You might be asking. NPX is a way for me to not have to type dot slash node modules slash node mon slash whatever or whatever the command for Nodemon is. I don't want to be typing the relative path. It's probably under bin or something. Let's look node modules dot bin. You see it dot dot bin. There's a nodemon command here. So if I want to run it. I'm using Windows by the way, so it'd be backwards slash, but if you're using Mac or Linux is forward slash here. So mine would be backward. So if I want to run that nodemon command under node modules slash dot bin, I have to type it in full here. You know, server dot j s. Okay, that's a bit too much. I don't want to write the whole path. So that's why I use NPX. Okay. So instead of writing this whole thing here, I just write NPX nodemon server dot j s. So NPX will do the job of finding nodemon in this bin directory. That's in the node modules here. That's why I use NPX. Okay, so now watch what I do. Go to server dot j s. I'm going to go here and remove this comment. And save it. Did you watch the terminal? I didn't kill the server at all. And it said restarting due to changes. Starting node server again. So here's my server link listening message. Okay, so that's very helpful so we don't have to always kill the server and restart every time we make a change. That's node one. Now that's nice. What if I don't want to say just slash I want to go to a route called hello dash world. So I want to go to the browser here and be able to say, okay, I want to go to localhost 3000 slash hello dash world. How do we make this kind of named route here? That's easy. We just change the first argument to the get function. So we go here. We see get see that. So that's slash say hello dash world. So whenever the user goes to slash hello dash world, it will hit this endpoint. Save that you can automatically see it. Node one automatically restarted for us. Go to the browser. Now if you refresh, there's no more hello world here. So you have to say hello dash world and that's when that endpoint is hit. Let's go back to the code here. So now let's do something more interesting. Let's send back HTML, right? HTML page. How do we do that? That's easy. Instead of sending this string, you can start writing the HTML here. Okay, let's make the HTML tag. Don't forget to close it. And then inside within between the open and close, let's do the body tag. And then forget to close the body tag. And then finally, I'm going to write a message, a paragraph, put a paragraph here. Hello world. Okay, you need to be familiar with HTML. So I assume everybody knows a little bit. Just write the tags with the angle brackets surrounding them. So open tag for HTML, open tag for body and open tag paragraph. And then forget to close them. And let's save that. Go to the browser, refresh. If I open that tools, I want to inspect this. You can see that HTTP body and P hello world here. It's actually HTML that was returned. This will be the elements tab in Chromium based browsers. I'm using Firefox. There should be an elements tab that you can see the DOM. Alternatively, you can right click and click build page source. And you can see we return this. It's giving me the error. You need to provide the doc type. Okay, you can close that. So to verify the request, I click network tab and reload. You can also see here the response headers. You see the response is here, right? Hello world. You can see raw. Raw is what it looks like. And then the headers. Let me just check the response headers. So one thing that we want to do when we send back HTML is to send a content type. Like this, you accept text HTML. Usually we add a content type header to that response. But the browser here recognized that's actually HTML. So that's why I render like that. So now I want to talk about how to set headers. You can see all these headers are sent in the request of response. We can also send our own header to add some more information about the response. And the one I want to do is content type. That's a very common type of header to satisfy what kind of response is this. Is this plain text? Is it HTML? Is it application JSON? So let's do that. Go to the register code. Here before I do the send, I'm going to say res.set. Whoops. And what this does, let me change my spaces to two because I like two spaces. Indentation. So I can set, give two arguments. The first is the header name. I put quotes, content, dash type. The second is the value for this. So I want to say tax slash HTML. This is the header, content type for HTML. You got to write it like this. Tax slash HTML to let the browser know, okay, I'm sending back HTML. So it's, in this case, it recognized it was HTML, but usually you want to set it to be properly parsed by the browser. So you want to say, hey, I'm sending back HTML. So you should render it as HTML, not any other kind of file or content. So when I say res.set, I'm setting a header to be sent in the response. Res is the response object. We can call set name of the header and the value as a second argument to that set function. Make sure to call it before you call send, okay? Now save that node bond restarted the server for us. And then we want to go back here to the browser. Save the set to the browser because input the button to say, let's be Plans, let's save thisاص key here saying config. biAP doesn't actually have a siellä button. I can press it. So the link that you get to call the browser is solved, so that it can be ran with Yu Yu reading. And wait, it should still get the whole action at first and then then anzus code with it. But let's say I'm going to create another header for that folder right next to it. instead of making a request to the server, it just downloads the local version. Not only, we don't really want to do that because we're developing locally, but that might affect your responses, you know, because I'm developing real time and changing things a lot, so I'm gonna disable cache, so it never does that, okay? Make sure to turn it back on when you finish developing. Let me see if it does it right. Okay, now it's here. You can see content type in the response headers. That's what I said there. Content type is tax HTML. And there's also this additional care set for UTF-8. It's probably added by Express, I don't know. Just to make sure this content is encoded in UTF-8. And if you wanna parse this, use decoded using UTF-8. But what matters is it says text slash HTML, so we identify this response as sending back HTML so the browser doesn't confuse it with something else. Okay, I'm gonna keep going. I know we're kind of on the hour. I'll try to be fast so we can do a little bit more things. Going back to the code here, let's learn how to change the status. You know, have you ever heard of 404 not found when you access a page that doesn't exist? So that's the status code for HTTP. So if you wanna set the status quo, we can do so before the send. You can say res.status, for example, 404, right, not found. You can do that. Let's actually make a different response. I wanna make a not found page. Let's do that. So we're gonna go outside this get. I'm gonna say app.get. And I'm gonna say slash not found, literally saying not found. And I'm gonna say function, rec, res. It's always the same pattern, okay? One argument for the endpoint path, and the second for the handler function. And then let's res.send a page that's HTML, body. I'm gonna just say not found. In the body there. And what I'm gonna do here before that is say res.status, 404. That means when I send this request, I wanna change the status code for HTTP to be 404, which usually means not found. The normal status code, when we did the hello world, is 200, which means okay, 200 okay. Okay, so let's, we'll see that in the browser. So let's go here and look at the browser, refresh. Now I can see hello world, see 200 okay here, status. That's what I mean with status, okay? Now if I go to not found here, instead of hello world, you're gonna see status 404, because we changed that by saying res.status, parenthesis 404. So that's a way of manipulating the status. 404 just usually means not found. So if you wanna say that something was not found when somebody accesses, okay, somebody's asking for a product information. And then you say, okay, we don't have that information, so we're gonna say send back to the client, hey, we didn't find anything, so we're gonna say 404 not found. That's an indicator that the resource was not found. Okay, so let's see the questions. Why not put the header inside the res.send? So the way we usually work with express is we call on the res, and we do the operations, everything that's necessary to manipulate the response before we actually send. Send is like the closing deal, right? You do, you write a response, you do whatever is necessary. It's like writing a letter, okay? I'm gonna write this and that and that. I'm gonna put some images here, I'm gonna make this happen, and I'm gonna put the stamp and whatever. Once I'm ready to send, put in the mailbox, right? It's when I call send. That's the last operation we have to do. So make sure to do everything before, like setting headers, status code and everything. Just keep the send only for the thing you're sending here. You're not sending the whole thing in send. Send is just meant for sending either the string or the HTML content, that kind of stuff, okay? It's not the other stuff. The other stuff is done separate. Let's move on. So we saw for a phone or a phone. Let's do, okay, this is nice, right? But we don't wanna be writing HTML in JavaScript code here. That's really tedious. Imagine this is just one thing, right? One message. Imagine a whole website full of text and interactive elements. This would be a nightmare. So we don't usually do this. We actually start this in a file that's separate. Let's go here and create a file. Let's do the hello world. I'm gonna go create a file called hello-world.html. And let me open split down so I can have it here. So go to server. I'm gonna take all this content that's sent for hello world, cut putting hello world.html. You can add line breaks if you want to make it easier to see up to you. Doesn't really matter, okay? There you go. That's much nicer. Now it's a separate file. Now we need to send it here somehow. But to do that, we first need to read the file in order to send it back to the clients. So to read the file, we need a help from the FS or file system module from Node.js. Okay, and to do that, we go up here. We have to require it. Now it's built in so you don't have to install it in NPM, okay? So we just say, require quotes FS. FS is file system. Put that in a variable. As you call it, the same name as the module, FS. Okay, and then we're gonna call it here before we send. Okay, we need to read a file. So FS has many functions. Okay, one of them is read file sync. That's meant to read a file. Now you need to know, okay, call is a function. Where's the file? So you need a path. Put under quotes, let's say, hello-world.html, that's the file path. Cause it's in the current directory, right? So I don't have to type the whole path. It's relative here. Okay, now comma, we can pass some options. I usually always like to pass the encoding. Otherwise it doesn't parse the file correctly. And I'm gonna pass on the object here. And this object has the proper encoding. And the value is gonna be UTF either eight or dash eight. Either one's fine. So that means, okay, read this file, but I want it to decode it using UTF-8. That's what we usually use today to encode our files, text files. Okay, once we do this, it will return a string with the content for the HTML. So we can put that in a variable. Let's say HTML content. And finally, to send it back to the client, just put the variable which I'm a content here. Okay? So when it calls read file sync, it takes this file, content, and imagine it was placed here like that. And then this variable goes here. Imagine it was like that, okay? As a string. All right, I'm gonna revert my code to what it was. Let's see if it works. Save that. Go to the browser. Go to hello world, back to hello world. Does it still say hello world? Yeah. Okay, so that works. Okay, so back here. If you wanna learn more about the FS module, let me show you how to see the docs. You go to doc.js website, doc.js.org. Click docs in the menu, navigation menu, and make sure you click the version that you have, okay? In my case, I think I have 20. So I'm gonna select 20 there. Make sure you're using the version you have. If you wanna find out what version you have, go to your terminal and you type node space-v, and it will tell you what version. Oh, actually I'm not using 20. It's actually 18.16. So I should go there and make sure to change my version here to 18. Otherwise, I might be referencing documentation that's either old or too new, that it might have stuff that I don't have or stuff that might have been changed. So make sure to choose the right version. Now you're gonna scroll down and go to whatever you want. In this case, file system. See that? Click file system. Then here it says all the functions available to you. You can go through it manually. It's gonna be tedious. I like to press control F and I can find in page, read file sync. You see I found that, I click there and I understand I can read this to see what the function does. You can see there's a path argument and an optional, the square brackets means optional options. So path and then the options encoding, seed encoding there. And there's some examples that they provide. But this is how you read the docs for all the built in node modules. Okay, so I'm gonna go one step even further in the code. Let me just do your code. Now if you notice, we have one endpoint or one route, just for one page, right? Hello world. And then we would have to do the same for the not found, right? Create a not found here. Let's do it. Not found.html. Let me put it down here. Then I'm gonna do the same here. Cut this thing, put it there, and then I gotta go okay. FS.readfile sync, what's the file name? Not-found.html. Okay, put the options for the encoding. In an object encoding string utf-8, put that in the variable, HTML content. And finally send that content out of variable. You can see I'm repeating myself, right? And imagine the website today, many websites have so many pages. This is not scalable, right? Meaning this is not gonna work out well. I have to keep doing the same thing over and it's gonna be a mess. Okay, that's a better way to do that. And I'm gonna learn about a metaware for the static files. So HTML files, images, fonts, JavaScript files, CSS files, on the client side, they're all called, you can consider them as static files. Okay, you can think of them as assets, right? Image assets, fonts and everything. So let's put them in a directory I'll call public. Move all the HTML there. Public is gonna be all for the static files, like in HTML pages. So I move all of them there. I created the directory public, move the HTML files there. This is out of don't save, that's... Okay, now what I'm gonna do here, after I do my app, is I'm gonna kind of install a metaware. So I'm gonna say, app.use parentheses, the use is a way for us to use a metaware. And this metaware comes from the express variable here, dot static, and then you gotta call it with the name of the directory you wanna serve as a static, the static files. Now I need to explain to you what is a metaware. So metaware is basically intermediate between the request and response. So when a request comes in through express, it will pass through many functions that do things for you. And these are called metaware functions. And they do some work before it actually reaches the handler function here for the endpoint that will ultimately send back the response. So if you get a request, it will pass through the metaware functions. After that, it finally reaches this handle function that you define for this specific route. So this metaware here is for static files. What is it doing? Basically it's doing this, what I already did here. It's reading the file, it's setting content to whatever, HTML, all this stuff. And it does so by looking at a specific directory, in this case public. So if you try to access, it's gonna serve this public directory and it's gonna do that's hello world and dash not found because the file names here correspond to these. So it takes the route from the file name. Notice it's not gonna have the prefix public, okay? That's not gonna happen. You don't have to type public. Public is just meant to be, okay, this metaware will go to the public directory and take everything there and define all these endpoints to serve these static assets, these pages. So no public, you're not gonna type public, you're just gonna type whatever the file name is. You don't need to type HTML.html. So with that, we don't need to do this anymore. You can just either remove, I'm gonna comment it out. So when I comment the code, it's not executed. I can just remove it. Or I can leave it there for reference for you. But this is not executed at all, okay? So let's try it out in the browser. Do I still see hello world? Oops, did it work? Did it not work? Oh, I had to type the HTML, nevermind. I thought I wouldn't have to. And what's the other one, not found? Not working? Okay, let's debug this. Go back to the, did I type it right? Not found. Oh, there's nothing. That's why. What's going on? I removed the thing. Okay, HTML, body, not found. Let me put the content back there. Go back to the browser. Oh, there you go. All right. Yeah, so in this case, you'd have to type the full file name, but I think there's a way to not have to type HTML. Maybe if I made it a folder, let me just explore that a little. I wonder what would happen. If I make it index.html and put it inside hello world. Folder, let's try that. Save the server to restart. Let's try that slash hello world. Ah, now it works. So that way it works. I wonder if there's an option for that middleware to not have to type HTML. There might be. But the way I did this was creating a folder hello world and redaming the file to index. So when we say slash hello world, it automatically fetches the index page. Okay, so that's the static middleware to provide static assets. So you would put all your HTML under public and it would serve automatically. So I don't have to define an endpoint, a get endpoint for each file that I have. I don't need to repeat myself. It's basically doing all of this for me. If you want me to go over JSON very quickly, if you still have time, we can do that. Otherwise, we can wrap it up. Thomas asked, it could be quite complex as the website gets complex. Is there a way to avoid putting everything on file? Yes. Typically, we don't put everything on one file. We separate to various different files. Each with a separate concern. So you can do that. You can define all of your endpoints, say for products in a folder with products and put all your files related to products there. Another for orders and so on. So this is nice, but today, when we make servers, we made what are called APIs. And APIs typically serve a specific format. That's not HTML, but rather a text, plain text in what's called JSON, JavaScript, object notation. Pretty much, if you look at package.json, this is the JSON format. So the responses from web server would typically look like this. With property and value pairs. So how we do that? Well, it's actually very easy. Let's go here and create an endpoint to get certain products. Let's go here. I'm gonna say app.get versus argument string slash products. Second argument of function with two parameters. Rec, res, separated by comma, code of brace. Now we're gonna send here res.send and watch what I'm gonna do. I can actually send an array of objects. Let's say ID is one, name is, I don't know, iPhone. 15. So this is a array, JavaScript array. With an object, this object represents a product, right? It has an ID and name, and it could have a lot more properties. Let's simplify, make it simple and have just that. Let's try this out in the browser. When I say slash products, watch what happens. I get back JSON. Now if I click the DevTools Inspect, I can say 200K and Content Type Application JSON automatically set for us. And the response, that's raw, if I click raw, it's in an array of an object, everything in JSON format. Now my browser Firefox here is very nice. It recognizes the response as JSON and it makes this very nice interface. But the raw data is like that. Okay, see that. And if you want the pretty print like that to make it formatted nicely for us to better see, and if you like the JSON interface from the browser to visualize the data, it's like that. So that's just it. Just send back either an array or JavaScript object. And it will automatically send JSON. Now there is a function called JSON. That's meant to be just for JSON. You can do that as well. But send is like a general function. It will understand if you pass, try to send back plain text or HTML or JSON, that kind of stuff. Okay, so typically what would happen is you would have a database and then you take the products from the database, query the database for products, and then you start them in a variable here, like products, and then you do some processing if you need and send back products. This would be the database somewhere. So most of the time today you would be working on what's called a backend server API that serves data back in JSON format. That's pretty much the most popular standard today of. Traditionally the server would send HTML, and every click on a link or a page would be a request to a new page. But things have changed and the server signed kind of separated from the client side. So now we have different things. We have the front end applications and we have backend applications, and they kind of separate now. But in the beginning they're all together. That's why I showed you. You can send back HTML. But today we just sent back text in format JSON, and then the front end would be responsible for taking that data and somehow showing it using HTML elements and so on. It uses JavaScript on the client side to build all the pages and construct everything based on the data that's provided by the backend API serving JSON. Okay, I think I wanted to show a lot more. I think I'll leave that for the next time. We're out of time.
No comments yet (loading...)
No comments yet (loading...)
Did you like the lesson? 😆👍
Consider a donation to support our work: