[0:02]So earlier in section two, where we talked about Node's module system, you learned about this HTTP module. We use this to create a web server that listens on port 3000 and responds to requests to these end points. So the root or API courses. Now, while this approach is perfectly fine, it's not ideal for building a complex application. Because in a large complex application, we might have various end points, and we don't want to hard code all these if statements in this function. So in this section, we're going to look at Express, which is a fast and lightweight framework for building web applications. So next, we're going to look at restful services.
[0:51]Let's start this section by a brief introduction to restful services, also called restful APIs. If you already know what rest is all about, feel free to skip this video. So earlier at the beginning of the course, I introduced you to the client server architecture. So most, if not all applications we use these days, follow this architecture. The app itself is the client or the front end part. Under the hood, it needs to talk to the server or the backend to get or save the data. This communication happens using the HTTP protocol, the same protocol that powers our web. So on the server, we expose a bunch of services that are accessible via the HTTP protocol. The client can then directly call these services by sending HTTP requests. Now, this is where rest comes into the picture. Rest is short for Representational State Transfer, and I know it probably doesn't make any sense to you. Because it was introduced by a PhD student as part of his thesis. But the theory aside, REST is basically a convention for building these HTTP services. So, we use simple HTTP protocol principles to provide support to create, read, update, and delete data. We refer to these operations altogether as CRUD operations. Now let's explore this convention using a real world example. Let's say we have a company called Vidly for renting out movies. We have a client app where we manage the list of our customers. On the server, we should expose a service at an end point like this: HTTP vidly.com/api/customers. So the client can send HTTP requests to this end point to talk to our service. Now a few things about this end point you need to know. First of all, the address can start with HTTP or HTTPS. That depends on the application and its requirements. If you want the data to be exchanged on a secure channel, you would use HTTPS. After that, we have the domain of the application. Next, we have /API. This is not compulsory, but you see a lot of companies follow this convention to expose their RESTful services. They include the word API somewhere in the address. It can be after the domain, or it can be a subdomain like API.vidly.com. There is no hard and fast rule. After that, we have /customers, which refers to the collection of customers in our application. In the REST world, we refer to this part as a resource. We can expose our resources, such as customers, movies, rentals, on various endpoints. So this is our endpoint to work with the customers. All the operations around customers, such as creating a customer or updating a customer, would be done by sending an HTTP request to this end point. The type of the HTTP request determines the kind of the operation. So every HTTP request has what we call a verb or a method that determines its type or intention. Here are the standard HTTP methods. We have GET for getting data, POST for creating data, PUT for updating data and DELETE for deleting data. Now let's explore each of these using our customers example. To get the list of all customers, we should send an HTTP GET request to this address. Note the plural name customers here. It indicates a list of customers. So when we send an HTTP GET request to this end point, our service should send us something like this. So we have an array of customer objects. If you want a single customer, we should include the ID of that customer in the address. Then our server would respond with a customer object like this. Now, to update a customer, we should send an HTTP PUT request to this end point. And note that again here, we're specifying the ID of the customer to be updated. But also, we should include the customer object in the body of the request. So this is a complete representation of the customer object with updated properties. We send this to the server, and the server updates the customer with the given ID according to these values. Similarly, to delete a customer, we should send an HTTP DELETE request to this end point. But here we don't need to include the customer object in the body of the request, because all we need to delete a customer is an ID. And finally, to create a customer, we need to send an HTTP POST request to this end point. Note that here, because we're adding a new customer, we're not dealing with a specific customer, so we don't have the ID in the address. We're working with the collection of customers, so we're posting a new customer to this collection. And that's why we should include the customer object in the body of the request. The server gets this object and creates a customer for us. So this is the RESTful convention. We expose our resources, such as customers, using a simple, meaningful address, and to support various operations around them, such as creating or updating them, using standard HTTP methods. So throughout this section, we're going to learn how to use the Express framework to build a RESTful service for managing the list of customers. However, in this section, we won't be doing any database work, because that will bring in additional complexity. Our focus will be purely on building HTTP services, and we will use a simple array in memory to keep the list of our customers. Later in the course, we'll look at using a database.
[6:51]So here's the code that we wrote in the section about Node Core, where I introduced you to the HTTP module. So you can see with HTTP module, we can create a web server. Here we have a callback function that takes two parameters, request and response. And with this request object, we can check the URL of the incoming request. So with this, we can define various routes for our application. So if we have a request for, let's say, /API/courses, this is how we're going to respond to the client. Now, while this approach certainly works, it's not very maintainable. Because as we define more routes for our application, we need to add more if blocks in this callback function. So that's when a framework comes into the picture. A framework gives our application a proper structure, so we can easily add more routes while keeping our application code maintainable. Now there are various frameworks out there for building web applications and web servers on top of Node. The most popular one is Express. So if you head over to npmjs.org or npmjs.com, Here, let's search for Express.
[8:09]So the current version is version 4.16.2. Let's have a quick look here. So here on the right side, look at the statistics. There have been over 700,000 downloads in the last day, and over 15 million downloads in the last month. It's a very popular framework. It's also very fast, lightweight, and perfectly documented. Now, back in the terminal, let's create a new folder for this section. So, I'm going to call this Express demo. Now, let's go inside this folder, run NPM init with yes flag. So now we have a package JSON file. And finally, we can install Express.
[9:01]Beautiful. In the next lecture, I'm going to show you how to build your first web server using Express.
[9:12]All right, now in VS Code, let's add a new file, index.js. We could also call it app.js, it doesn't really matter. So in this file, first we want to load the Express module. So we use our require function, give it the name of our module, which is Express. Now, this returns a function. We call that Express. Okay? Now we need to call this function like this, and as you can see, this returns an object of type Express. By convention, we call this object app. So we store the result in a constant called app.
[10:00]So this represents our application. Now, this app object has a bunch of useful methods. We have methods like get, post, put, and delete. All these methods correspond to HTTP verbs or HTTP methods that I told you about earlier in the section. So if you want to handle an HTTP POST request to an endpoint, you would use app.post. Now in this lecture, we just want to use app.get. We want to implement a couple of endpoints that respond to an HTTP GET request. So this method takes two arguments. The first argument is the path or the URL. So here I'm going to use slash to represent the root of the website. Now the second argument is a callback function. This is the function that will be called when we have an HTTP GET request to this endpoint. So this callback function should have two arguments: request and response. So this goes to a code block. Now this request object has a bunch of useful properties that gives us information about the incoming request. If you want to learn about all these properties, it's best to look at the Express documentation, because in this course, we're going to use only a handful of these properties. So head over to expressjs.com. On the top, look at API reference, version four. Now here you can see the request object, and below that, you can see all the properties that are available to you. You have base URL, you have body to read the body of the request, cookies, fresh, host name, IP, method, original URL, parameters, and so on. So back to our code, when we get an HTTP GET request to the root of our website, we're going to respond with a Hello World message. So response.send Hello World. So this is how we define a route. We specify the path or the URL and a callback function, which is also called a route handler. Now, finally, we need to listen on a given port. So we call app.listen, we give it a port number like 3000, and optionally, we can pass a function that will be called when the application starts listening on the given port. So, once again, we use the arrow function syntax to display something on the console. So console.log listening on port 3000.
[12:54]Now, back in the terminal, Node index.js. Okay, we're listening on port 3000. Now let's switch over to Chrome and go to localhost port 3000. So here's our Hello World message. Now let's define another route. So once again, we're going to call app.get. Now this one is going to be /API/courses. Once again, we pass a function with two arguments, that is request and response, and this goes to a code block.
[13:34]Now, in a real world scenario, here we want to get the list of courses from the database and return them. But as I told you before, in this section, our focus is purely on building these end points. We're not going to do any database work. So I'm going to simply return an array of numbers. So response.send, we pass an array of three numbers. In the future, we can replace these numbers with actual course objects. So save. Now, back in the terminal, we have to stop this process and start it again. So, press Control and C. Okay. One more time, node index.js. Now, back in Chrome, let's head over to /API/courses. Look, we have an array of three numbers. Beautiful. So this is what I want you to pay attention to here. In this implementation, we don't have those if blocks. We define new routes by calling app.get. And with this structure, as our application grows, we can move some of these routes to different files. For example, we can move all the routes related to courses to a separate file, like courses.js. So Express gives our application a skeleton, a structure.
[14:59]So far, you have noticed that every time we make a change to this code, we have to go back in the terminal and stop this process and start it again. This is very tedious. So I'm going to show you a better way. We're going to install a Node package called Nodemon, which is short for Node Monitor. So, in the terminal, NPM install -g Nodemon. As I told you before, if you're on Mac and you haven't configured the permissions properly, you need to put sudo at the front.
[15:42]All right, Nodemon is installed, so, with this, instead of running our application using Node, we use Nodemon. Okay? Now you can see Nodemon is watching all the files in this folder. Any files with any extensions. So if you come back here and make a simple change and then save the file, Now, look in the terminal. Nodemon restarted our application or our process due to changes. So we don't have to do this manually anymore. Now, back in the browser, if we send a request to the root of the website, we can see our new message displayed here.
[16:31]Now, one thing we need to improve in this code is this hard coded value for the port. So we have used 3000 as an arbitrary number. While this may work on your development machine, it's unlikely that this is going to work in a production environment. Because when you deploy this application to a hosting environment, the port is dynamically assigned by the hosting environment. So we can't rely on 3000 to be available. So, the way to fix this is by using an environment variable. Typically, in hosting environments for Node applications, we have this environment variable called port. An environment variable is basically a variable that is part of the environment in which a process runs. Its value is set outside this application. I'm going to show you how that works in a second. So in this application, we need to read the value of this port environment variable. And the way we do that is by using the process object. So we have this global object called process. This object has a property called env, which is short for environment variables. And after that, we add the name of our environment variable. In this case, port. So if this is set, we're going to use this. Otherwise, we're going to use 3000. Now, we can store the result in a constant called port. Okay? Let's delete this. And finally, we need to replace 3000 with port and also change our message accordingly. So I'm going to replace the single code with back tick, so we can use a template string. And here we're going to replace 3000 with a dynamic value. So we add dollar sign, curly braces, and then add our constant. In this case, port. Okay? Now, back in the terminal, let's run this application using Nodemon.
[18:34]So on this machine, you can see I don't have an environment variable called port. That's why 3000 is used as the port for this web server. Now, I'm going to set an environment variable. So let's stop this process. On Mac, we can set an environment variable by executing the export command. If you're on Windows, you should use set. So export or set. Now we add the name of the environment variable, in this case, port, and set its value. I'm going to use 5000. So now we have this environment variable called port with the value of 5000. With this, when we run this application, Nodemon, you can see that now we are listening on port 5000. So this is the proper way to assign a port to your Node applications. You should attempt to read the value of an environment variable called port. If there is a value, you should use that. Otherwise, use an arbitrary number for your development machine. All right, now let's see how we can update a course.
[0:09]So let's add a new route handler. App, we use the put method for updating resources. Now, the path should be /API/courses. And here we need a route parameter, because we're working with a specific course. So, ID. Now our route handler, request and response, goes to a code block. Now here's the logic we need to implement. First, we need to look up this course with this given ID. If the course doesn't exist, we need to return a 404. That means resource not found. Otherwise, we need to validate the course, make sure it's in good shape. If invalid, return a 400 error, which means bad request. And if we get here, that means everything is good. So we update the course and finally, we need to return the updated course to the client. This is the logic we need to implement. So, we already have some code that we can reuse here, so I'm not going to type everything by hand. I'm going to copy some code from our other route handlers. So first we want to look up the course, and if it doesn't exist, we want to return a 404 error. For that, I'm going to go to this other route handler where we get a single course. This is the logic we're interested in. So we look up the course, and if it doesn't exist, we return a 404 error. So, copy these two lines. Paste it here. Second part is all about validation. For that, I'm going to go to our POST end point, where we validate the request body and send the 400 error. So here we need to copy the schema as well as this line for validating the request body using Joy. So copy these two lines. And paste it here. So we're validating. And if it's invalid, we need to return a 400 error. So I forgot to copy that line here. If we have an error in the result, we're going to return this 400 error. Okay? So let's copy that as well. Paste it here. So this is our second part. We have the schema, we validate, and if we have an error, we return a 400 error. We're done with the second part. Now the third part. So at this point, we have a course object, we can update its properties. So, course.name, we set that to request.body.name. And of course, if we have other properties, we'll set them here as well. So we're done with updating the course, and finally, we need to return the updated course to the client. So response.send this course object. Now let's test this. So back in Postman, let's change put to delete. First, I want to send an invalid course ID, like 10. Send. So we get a 404 error, not found with this message. Perfect. Now, let's delete the first course, course with ID one. Send. So we get the same course object in the response. And if we go to our second tab, where we have the list of our courses, So, look, we don't have our first course anymore. We only have courses with ID two and three. All right, before we go any further, I realized we have a bug or actually three bugs in this code. So look at the handler for responding to put requests to this end point. If we don't have a course with the given ID, we return the 404 error to the client. But at this point, we should exit this route handler. Otherwise, the rest of this code will be executed. So the proper way to implement this route handler is like this. So if we don't have this course, we return the response, and then we don't need a code block. So we can put everything in one line. That's much more elegant. We have the same issue in the handler for delete requests. So, if we don't have a course, here we should return immediately. Now, the delete route handler. So if we don't have a course with the given ID, we return the 404 error to the client. But at this point, we should exit this function immediately. All right, now it's time for an exercise. So from this lecture, we're going to start building the backend services for our Vidly application. As I told you before, Vidly is an imaginary service for renting out movies. So throughout this course, we're going to build the backend of Vidly bit by bit. Your first task is to create a service for managing the list of genres. So each movie has a genre like action, horror, whatever. We should have an endpoint for getting the list of all genres. Because somewhere in our client applications, perhaps we have a dropdown list for the user to select a genre. So we need an endpoint to get all the genres. We should also be able to create a new genre, as well as update or delete an existing one. So, before going any further, I want you to put what you have learned so far in practice. So even if you're an experienced developer, don't say, "No, Mosh, I know how to do this. This is so easy." I know it's easy, but what matters now is that I want you to get used to this syntax.
[1:26]So, go ahead, start a new project from scratch, call it Vidly, and build this HTTP service for managing the list of genres. You can see my solution attached to this lecture.



