1.3 Handling Static Files
1.Introduction4 lessons, 28:03
2.Displaying Content5 lessons, 38:57
3.Handling User Input2 lessons, 20:19
4.Conclusion1 lesson, 01:22
1.3 Handling Static Files
In the previous lesson, we started looking at happy by writing a very simple application. It listens for a request to the root of our application. And then it calls a handler function that returns some html. And of course we saw the results of that in the browser. Now, for a RESTful API that's the basis of your application. You basically just write your outs and you're done. Now, of course there's other things that we need to go over which we will talk about in a few lessons like route parameter and things like that. But for the most part, that's the basis of your restful api application. But for a typical web application, you need to serve assets. things like CSS, images, java script. Maybe even some HTML files. So in that case, we need to set up our application. To handle those types of requests because it's not going to do it by itself. For example, let's start up our application. Let's add a folder called public. Now, in many projects you will find that all of the public available assets. Those are things that would be returns to the client. They would be inside of a folder called public. It might also be called www route. It could be called, well, anything. It's up to the developer or the team that is developing the application. But in most cases, you will see public there. And inside of public, we are going to create a new file called indexhtml. Let's go ahead and give it some content. Let's set the title to index. In the body, we'll say this is the index. Let's also say that this is a static file. Just so that we know that whenever we see this is a static file, that's, well we know it's a static file. Okay, so with that running we can try to make a request for that exact file, recite within the public folder And it's called index HTML. It returns a 404 because our application is not set up to do that. So, we have to tell our application practically everything we want it to do, and that's perfectly fine. So, we want to tell our application to serve Cedec assets and to do that, we use a plug-in. Called inert, so we want to install this. We of course want to save it to our project. It is just a plugin that we are going to register within our application. So let's start up our application once again and let's register the inert plugin. So we do that with our server object. We have a method called register. And then we require our plugin. Now this is going to give us an error, but look at what this error is: cannot start server before plugins finished registration. That basically means that plugin registration is asynchronous. In our case The start method executed before the application could register the immerged plugin. So the register method which is a promise. One way we can get around this is to simply use the verm method and then have a fall back function. And then put our code inside of that callback. And let's do that, we will see the result in the browser, which is going to be well, basically the same behavior. And so if we refresh, there we go. If we look at the console, we see that there is no error. However, at the time of this recording, it is 2018. We have new features that we can use that make working with asynchronous processes a little bit easier, and that is the async and await keywords. Now, if you're not familiar with these, That's okay, this is a good example. So what we are going to do then is create an asynchronous function. And inside of an asynchronous function we can easily call other asynchronous things. So to create an asynchronous function we use the async keyword and then we have our function body. So the first thing we want to do is register. Our inert plug in so we will do that by saying await and then we will register inert now the reason why we are saying await here is because register is asynchronous. So it's returning a promise. So we're going to await that, so that while our application is registering the plugin it can do other things. And then we will set up our route so we will do that. And then we will start our server now the start method is asynchronous as well so we could just say await and then server start and then we will write our message to the console and there we go, so we have an asynchronous function called start And inside of start we are going to register our inert plugin. We are awaiting that because it's asynchronous. We are setting up the route, then we are starting our server. Now the last thing we need to do is call this newly created start function. And once again we don't get an error, in the browser, if we refresh the page, everything behaves as it did before. However, if we try to make a request for index.html, and of course, it doesn't work, if we make a request for public.html, that doesn't work. So what we want to do then, Is set a route basically, is what we're going to do. Now that we have this plugin, we are going to set up a route to handle a request for the index HTML. Now the route method, accepts a single object that contain the objects for our routes or we an pass in an array of routes. And that's what we are going to Change this too. Our first new route is going to be a get request. So let's go ahead and start with that. And the path is going to be /index.html. So we're setting out a route specifically for index.html Then we can have our handler function. So that is going to have the request and the response. And we could just return a string if we wanted to. And if we make a request for index html, We will see that strain. But of course that's not what we want. We want the file itself. So what we can do here is use our h object, the response and this has a method called file. And we specify the path to the file that we want to return. So that is inside of the public folder. And it's called index.html. So if we refresh the page now, we see that this is the index and that it is a static file. So there we go, that's how you handle static assets. I'm kidding. That is horrible, because we could have a ton of assets and setting an individual route for each one of those Not very sustainable so what we are going to do is use a feature that we will talk about in a couple of lessons called route parameters. We are going to setup a route, that is basically a catch-all, if it doesn't match an existing route then its going to try to take the segments from the URL And found the file on the file system. So what do I mean by that? Okay, so let's say that we made a request for slash CSS and insight CSS. So what we would have here are two segments, we have the folder CSS and then the file name, sight.css. So it's going to take those segments And then try to find a file inside of whatever directory that we specify that has that particular path. So what we are going to do is change our handler so that it's not a function, but instead it's going to be an object and it's going to have a directory property. And then we can specify the path. To this directory so that any request that doesn't match one of our other routes is then going to take the path of that route and try to find it inside of whatever directory we [INAUDIBLE] Specify so in this case. It's going to be public. So with that in place, we can go back to the browser. We can refresh the page and we see the same behavior. That we saw before. And we could also set up a default file. Most web servers have the idea of a default file so that if you don't specify a file then it will look for like an index HTML or default HTML. Well we have a property called index. And then we could specify whatever file names that we wanted to be writing for our files. So w could have index, we can have default and things like that. So, we could do that. Let's also create another folder inside of public. Let's call these pages, and let's have a new file called about html, just so that you can see. How it's going to take the path from the url, and apply that to inside of the public folder. So inside of about, let's add some HTML so that we have something to see, we'll say about and. this is the about static page. So whenever we go back to the browser, we can make a request for pages/about.html and we can see that it is finding that file just fine. We see it in the browser, and all of our other routes work. So we have essentially a route for index HTML because that's being handled by that catch all, if you will. But if we go to the root of our application we still see the behavior that we had before. And that alert is a little annoying, so let's go ahead and get rid of that. But for handling static files, that's basically all that we have to do. It's just a few lines of code. We do have to use that inert plugin, but once we register it and set up our route, then we can handle whatever static asset that we need.