 Hello, and welcome to my course on building web applications using Node.js and deploying them on AWS using their auto-scaling containers, also known as AWS Fargate. Now, a bit of introduction. So why are we going to learn how to code using JavaScript? Well, JavaScript is one of the most used programming languages in the world that has two very, very big advantages. One is the community support. Since there's so many people coding in JavaScript, that means that it's extremely probable that any issues or any bugs you run into, someone else will have run into them before you. And that's great because they will have probably posted about their bugs on forums such as Stack Overflow, and you will have better, quicker, easier access to the solutions that you may be encountering when you're programming your application. The second and also very important point is the job availability. Since a lot of people, a lot of companies are programming using JavaScript and Node, there is a higher availability for jobs, which means that you are going to be more likely to eventually in the future find a job programming JavaScript and Node, and that's why it's so helpful and useful to learn this language in the first place. Finally, but not least is that JavaScript is a fairly easy programming language to learn, which means it's easy to get into the learning curve is not as deep as other programming languages, but that also doesn't mean that it's not capable. JavaScript is one of the most capable programming languages there is to date, and that balance and mix of being fairly easy to learn how to program and its capabilities make it a great programming language to get started with. So the second aspect of this course is that we're going to be deploying our application on AWS Fargate. Now why use AWS Fargate? Well, AWS Fargate allows us to concentrate on coding our application in such a way that's fairly simple to do. We're going to be coding our application using a very traditional architecture and layout of the application, and then we can simply dockerize or containerize that application and send it to Amazon and have Amazon deal with the rest. So no matter how much traffic you're going to be getting, AWS Fargate will manage the whole process of receiving inbound traffic and detecting if, for example, there's a big spike in traffic, it will automatically spin up new instances of your containerized JavaScript application and thus be able to absorb that inbound traffic automatically all for you. So you will not have to worry about anything. Once your application is coded and you've set up AWS Fargate, once you've done that, you will not have to basically administer or set up anything else. Everything will be done for you and managed for you by AWS Fargate. And that's one of the convenient things about this is that it's also a very, very cost-effective solution because if your application is not receiving any traffic at all, then basically you're not paying for anything. And once you start getting traffic, then AWS Fargate, I mean, you have to receive quite a bit of traffic for AWS Fargate to actually have to start to spin up a lot of instances on your application. So likely you will not incur any costs, especially for this course, right? So it's a very, very simple solution and very practical solution to start coding your applications using AWS Fargate. So what are the course goals and what will you learn? Well, to begin with, you'll learn how to code JavaScript if you don't already know how to do that. This course is intended for complete beginners. We won't go over too much detail of the super low-level and beginner stuff because quite frankly, I believe in the methodology of teaching where you learn the things that you're actually implementing. So we will stick to practically no theory and just all hands on getting your hands dirty with programming JavaScript and learn as you go. Second of all, you'll learn how to build a backend application using Express, which is a Node.js framework for building web applications. Third, you'll learn how to do a or build a backend application that makes an API calls to external APIs. We're going to build a very, very simple web application. And then you're going to learn how to host that on AWS Fargate. As I've said before, AWS Fargate has a slight learning curve when it comes to setting it up. But once that's set up, which I will help you do, then it's all basically, you know, AWS managing everything and you won't have to do any other administration or setup or managing of anything else other than building your application and the code for your application. And finally, if you want optionally, you will be able to purchase your own domain name if you don't have one already and link it to your application that's running on AWS Fargate. So all of these are the things that we're going to learn over the course of this course. So what are some prerequisites for this course? Well, first and foremost, if you want to deploy your application on AWS, then obviously you will need an AWS account which you can open up on aws.amazon.com. Second of all, you will need a code editor. I'm going to be using VS Code because it's a great and more importantly free code editor, which everyone has access to. I also recommend using JetBrains WebStorm if you have it, but that's a paid code editor. Finally, you will need to install Node. Node is very, very easy to install. It's only a couple of steps, be it on Windows, Linux or Mac. I've left the notes and slides for the instructions to install Node on each platform. As you can see here, and there's also a separate course further along as you progress through the course lectures, you will encounter a course on how to install Node if you haven't done that already on your computer. Alright, so with a bit of theory out of the way, let's start to the actual fun part, which is the actual programming of our express application. Right before we start, I just want to mention one small thing. We're going to be building an express application which is going to represent a to-do list. We're going to build it in such a way which is optimized for learning. It might not necessarily be what a seasoned developer might do and then upload as a functioning web app to the cloud, in this case that we're going to do with AWS Fargate, but instead it's made for anyone beginning with Express or Node or JavaScript to learn the basics on how to build the express application. And then from there, you can do more advanced courses on how to, for example, integrate databases and store and persist data, so on and so forth. What we're going to be doing is we're going to be storing data on the actual hard drive as just physical files. We're not going to be using a database just because this course is very, very short and it's intended to cover the very basics of programming and getting an express application up and running. However, we are going to complete a functioning back-end to-do list app. So what this app is going to do is it's going to enable you to see to-do lists that you have, complete them and create new ones basically. And that's it, right? That's a very, very simple to-do list app and that's what we're going to be doing. So let's get started. I have Visual Studio Code open here. I've opened up a directory where I want to place all my files and build the actual project from this directory. And I've opened up the terminal. So the way you do this is terminal, new terminal, and this will pop up and as you can see here, we're inside of this directory. And so the first thing you want to do with any node application is to hit npm init-y. Okay, so what this will do, and by the way, if this command doesn't work, then you haven't properly installed node in npm. So please refer back to the documentation on the previous lectures on how to do that. So what this command does is, as you'll see in just a second, it will create a new file in this directory. Here we have it package.json. package.json is a standard file that any node project has and it represents the kind of like the structure of your project, right? So right now, this file is pretty empty. It's got some default values, name, version, so on and so forth. But we're going to need to build on top of this. Right now, any command, any node command you would do in this directory, it would recognize that this is a node project and hence, you know, you can do different node commands inside of this project, right? So the first thing we're going to do is, since we're going to be using ExpressJS to, you know, to create our web application, we need to install the ExpressJS library inside of this project. Right now, this project is empty. There's nothing inside of this folder aside from package.json. So the way we want to install Express is say, npm install express dash dash save. The dash dash save is important because as we're going to see in just a second, one of the things that package.json does is it holds all the different dependencies of our project. So what other third party libraries are needed in order for our project to run, right? And by doing dash dash save, what we're telling the npm install command is that not only do we want to install Express in our project, but we also want to save it as a dependency or, you know, explicitly save it as a dependency in our package.json file. So I'm going to hit enter and wait till it installs. And here, as you can see, we see that the npm command has automatically updated our dependencies list and it has included ExpressJS. Okay, so with that out of the way, now we can also see actually it's worth mentioning we can see a new folder that has been created. It's called node underscore modules. What this folder contains is all the different libraries that are needed for a project to run. And these are all the different third party libraries that we install with these npm commands, right? And as you can see, Express here. But we can also see that there's a ton of other different projects that have been installed already together with Express. And why is this? Well, it's because ExpressJS has its own dependencies as well. So our project is going to depend on Express, but Express also depends on all of these different libraries that npm has automatically installed for us. So like that, we don't need to keep track of what dependencies Express has. npm already knows that and installs all the different depending libraries for us. Okay, so now let's close this. Let's create a new file and call it index.js. And this is where we're going to actually code our application. Okay, so let's get started. The first thing we're going to need is we need to import Express. So the way we do this is we declare a new variable. We're going to declare it using the const keyword because we want the variable to be constant. We're not going to be changing this variable down the line. And we're just going to call it express. And we're going to set it equal to require, sorry, require, open brackets, and as a string type express. Okay, so now what we've done here is we are telling nodes to load the Express library or Express framework and then just store it in the Express variable. The next thing we want to do is we want to create an app, an Express app. So the way you do this now in Express is we want to create another variable and we're just going to call it app. So again, const app is equal to express. And the way you initialize the Express application is you just open and close parentheses. So now, not only have we imported the Express framework, but we've also initialized a app, a functioning Express app. And from here onwards, it's fairly, fairly simple. We can start to code the actual endpoints. But before we do that, it's probably worth mentioning how endpoints work in the first place. Okay, so I've opened up a new browser window and let's just see, let's just go to Google.com, right? Okay, I agree. Okay, so how do requests work and how does the actual web work? So what I'm doing here is I'm opening up the inspector tool in Chrome. Most browsers have this, Firefox has this. I'm using Chrome. You don't need to do this. This is just to explain how websites work. So I'm going to hit Inspect and I'm just going to rearrange this so it's a bit easier to see, okay? Okay, so now if I hit Network and I hit Refresh, you can see that there's a lot of things happening here. So all of these things, all of these lines here represent requests that my computer has done to Google in order to load the website to Google. So for example, the first one that's appearing here is a request URL to Google.com slash and then a couple of parameters here. It's a get request. So this is basically telling that our computer has done a get request to this URL which represents Google and then Google has responded back with what's called their response. So our computer is sending a request and Google is sending a response to that request and that's essentially how the internet works. It's all computers making requests to servers and servers sending responses back to us. And so here you can see the response that Google has, or response headers that Google has sent to us. You don't really need to worry about this but this is basically some metadata about the response that Google is sending back to us. More headers on the request that we sent to Google and then for the actual response itself you can see that this is the actual code that Google sent to us and then the browser, what the browser does is it interprets this code and then builds this visual representation of this code and this is basically how websites work, right? So in essence, all you need to understand is that whenever you type in a URL, for example, if you're browsing the web, what your computer is doing is it's sending a request to this URL and then that request basically holds some information that it's a request of type get. You're requesting this exact URL. It also sends the IP address for our connection, so on and so forth and then the server comes back with a response and that response can hold anything. In this case, it's the code for the browser to understand how to build the visual representation, right? Okay, so with that done, we can start programming the instructions for our application to handle these requests and kind of tell our application what it needs to send back as a response, okay? So we are going to be building a backend application. So that means that we're only going to be dealing with a backend side of things, so that's the actual business logic that processes the request and then sends information back down to the client, to the anyone using our backend application, right? So we're not going to be building a visual representation of our application in this course. We're just going to be dealing with the backend. You might have seen or heard about APIs. Essentially what we're going to be doing is building an API because we're not building the front end. We're not building the visual representation since we're only sticking to the backend. You can say that what we're building is an API for our to-do list, right? Okay, so let's get started. The first thing we're going to do is we're going to just build a quick Hello World example to see if our express application is up and running successfully. So the way we're going to do this is we're going to say app.get because it's a get request that we want to do to the root directory, so that's why we're going to type in a forward slash as a string, and that's the first parameter. The second parameter is essentially we need to define what's called a callback function in JavaScript, which is going to be processing the request to this root directory, right? So the way this works in Express is any callback function in what's called a HTTP handler, which is what we're defining here, has two parameters. It has a request and a response. So Express is going to be calling... Whenever it receives a HTTP request to this path, it's going to be sending both the request and the response information to our function handling this request. So we have to capture the request and the response, and then the body of the function, we need to define what we're going to be doing with the request and the response. So since this is a very, very quick Hello World example, what we're going to do is we're going to simply return the response and we're going to send a quick text, Hello World. And this is basically it, right? So anytime we hit the root directory of our Express application, we're just going to be sending a text which says, Hello World. The final thing that we need to do is we need to get our Express app up and running. And the way we do this is we need to define what port on our machine it needs to listen to for inbound traffic. So the way we do this is we say app.listen. We need to define the port. Typically on Express applications, you just do the port 3000. And again, the callback function for the listen is basically Express doesn't send us anything. So we just open and close parentheses because Express is not sending us anything. It's just a callback with no inputs as to tell us that the listen has started. So in our callback function, the only thing we're going to do is we're going to console log and say application running on HTTP, forward slash forward slash local host com 3000. Because we're expecting it to be up and running on this directory. So we've basically finished coding our Hello World example. Now what we can do is we can just say note index.js. And sure enough, it says our application is running on local host 3000. This is what we've typed in here. Now if you command click in my case, because I'm on the Mac, we go to the root direction and we can see that it's working. So this is excellent. Okay, so now let's get into the actual interesting part, which is let's code a to-do list. So I'm going to stop the server because every time we update the code, we're going to restart the server for now. There are ways to get around that, but for now for this course, we're just going to be restarting the server manually. I'm going to say also clear just to have a clean console. Okay, so let's get into the programming of the to-do list. So I'm going to create a new folder. I'm going to call it store because this is going to act kind of like our database. Again, we're not really going to use a database in this course just because it's a super introductory and quick course. So we're not going to use a database. Instead, we're going to be storing files physically on the hard drive in this directory. So just create a new directory, call it store and inside here, I'm going to create a new file called to-dos.json. Okay, and here I'm just going to copy and paste a bit of code. I'll leave it so that you can copy and paste it as well for yourself. But essentially, if I just structure this so it's a bit easier to see, what you're going to start to see is a, what's called a list. Anytime there's squared brackets in JavaScript that represents a list. So it's kind of like a collection of items, right? And in this list, we have three items, three objects as you call them in JavaScript. They have a couple of properties, an ID, a name, and a complete. So the ID is a number, one, two, three. Name is, you know, the name of the to-do list. So learn JavaScript, walk the dog and go shopping. And then the third property is complete. So if it's complete or not. So right now, none of these to-do lists are complete. Okay, so I'm just going to save this. I'm going to exit. Okay, so now to start to be able to, you know, access that information which you started there, we're going to need to import a new library. This library is called FS, which is shorthand for file system. So const FS is equal to require again. And we're just going to type in FS. This time we do not need to NPM install FS because FS is a library that comes already with Node itself, right? So you do not need to install this one. This is kind of, you know, a native library for Node.js. So I'm going to hit save. And now what we're going to do is we're going to create a new endpoint. So this endpoint is going to be app.get as well, forward slash to-dos. Okay. And again, request, response. This is what ExpressJS sends us. And now what we're going to do is we need to figure out a way on how to read this file that, you know, that we've just saved here and then send all of those to-do lists, items to the user as they request, you know, this, this endpoint. So the way we do this is we've already imported FS, which is going to be the library that we're using to read files off of the disk. So we can say FS read file. It's basically a property of this library. And now the first thing that we need to tell the read file kind of method is actually my, my, you know, visual studio code is actually hinting we need to provide the path. So what file do we need to open or where is it located? So in Node what we can do is we can pass as a string the relative path to this file. So relative means from starting from this directory, which is our project directory, how do we go about to find this file? So if you can, if you remember, we created a folder called store and then, you know, the file is just to-dos.json. So basically from the project directory, we need to go into the store folder and open to-dos.json. So the way you do this in Linux or in Mac, I'm not sure if it's a bit different in Windows, but the way you do this is you type in a dot, which represents a dot in Linux or Mac, represents the current working directory. So the current working directory is our project directory. And from the current working directory, we need to go into store and then we need to, you know, open to-dos.json, okay? We want to specify that we want to open this file as UTF-8 encoding. I'm not going to go into detail on what this means, but basically if we would skip this argument, then this read file function would open up the file as a byte array or as a buffer. We don't want to do that because we actually want to read it in plain English. So that's why we're telling it to encode the file as UTF-8. So like that, you know, we can just read it as plain English, basically read it as it is stored in here, right? Okay, so the next thing, read file is going to, you know, tell us to define is the actual callback function. So what do we do after the read file is complete? And here, you know, Visual Studio Code is hinting that there's two parameters that we need to take care of in there. So what happens, for example, if read file doesn't manage to open the file because maybe, you know, this file doesn't exist or I've misspelled the directory or whatever maybe. So it will return an error in some cases. And the data itself, if it's successful. Okay, so let's type in the actual body of our function. So the first thing I like to do is first get rid of the error. So what happens if there's an error, what do we do? It's not actually getting rid of the error. It's more like, you know, processing it or handling it. So if error, what are we going to do? Well, basically the only thing we can do is we can just say return response. So we're going to say, okay, we're just going to tell the user that, sorry, we couldn't find any to-dos. Please come back again later. It shouldn't really happen if we've programmed it correctly. But, you know, you never know. So let's just take care of the error as our first order of operation. So what we're going to do is we're going to say response.status 500, which is not really good practice. You shouldn't really be doing this. But it's basically, this is telling, express the same day HTTP status code of 500. So a quick introduction on what HTTP status codes are. So, okay, I've gone back to open Google and I'm going to go back to the first request that we have already seen. And here you can see that the status code was 200. 200 is a good status code. It's basically telling your browser that everything was okay. And Google found the content that you were looking for and it sent to you and there was no problem. So status codes starting with A2 are good. Status codes starting with a 4 are any kind of user-generated error. So that's, for example, when you're requesting a website to Google that doesn't exist. That's the famous 404 error. That's an error considered generated on the user end because you're requesting a website or a page that doesn't exist on the server. And status codes starting with a 5 are server-side errors. So this is basically not the user's fault. It's a server error that's happened and thus it's not really your fault and this is probably something that the company or the website should fix. Okay, so we're sending in a status code of 500 because this should work. If it doesn't, it's for some kind of strange reason, you know, it's kind of our mistake. And so we're just going to send in a text, sorry, something went wrong. Okay, sorry typo, something went wrong. Okay, so this is where we're going to send. Again, this shouldn't really happen. Okay, so now what happens if, you know, since we're actually returning something in an error, anytime you return a piece of code, then the execution stops here. The code won't go further down. So you can rest assured that if there's an error, then the code will stop here and whatever we keep typing here will not execute. But that's a great advantage and that allows us to have our code be programmed in a cleaner way because if there's not an error, then basically it will not go into here and our execution of the code will continue. And like that, you know, we can have code which is slightly easier to read, right? Okay, so now there's no error. What do we do with the data? Well, basically what we need to do is we need to load the content of the data which is being passed here as a callback function, but it's being passed as a string. So the first thing that we need to do is say const to dos is going to be equal to json.parse data. Now why are we doing this? So as I said before, we're reading this file in plain English and what we're receiving here is a string. A string is basically just plain text that we're receiving, but we want to parse this as a json file because this in essence is a json file and we want to make sure that we're parsing. When read file reads this as a string, we just want to make sure that we're parsing it as a json. So the final thing that we want to do is we want to return a response.json. A json of, and we're going to say to dos is going to be the content of to dos. Okay, so like that, what we're expecting is an object with a key of to dos and the content associated to this key will be a list of to dos the same as we have here, right? Okay, so this should be working. Let's do node index again, access our web app, and we need to access the to dos endpoint. Okay, so sure enough, we can see that our to dos are being loaded, so this is great. Now, instead of moving forward, instead of using our browser to check for our to dos, what I'm going to do is I'm going to use a tool called postman. Postman is a tool that allows you to do HTTP requests and test them and kind of have like a, you know, more convenient way to do these requests instead of doing a browser. Okay, so I have postman open, and like I said before, this is just kind of like a more convenient way to do requests when you're building APIs and backend applications. So you can download this for free. It's totally free to use. I'll leave the link to the URL to download this. In the description of the course, or you can just Google, you know, download postman and you'll have it there. Okay, so the first thing I'm going to do is I'm going to replicate the HTTP request that we're doing to our to-dos list to just have it here, right? So HTTP, first slide, first slide, local, host, 3,000. This will give us the hello world, but we wanted to dos. Okay, great. Right, so we can immediately see, right, this is much more convenient to see what we're getting back, right? It's well-formatted and everything's just nice. Okay, so let's go back to our code. Now, you know, this is all working, which is great. So the next thing that we want to do is we want to be able to maybe complete a to do. So we're going to build that right now. So let's say app.put. Now, we're doing a put instead of a get request, because typically in REST APIs, this is the better way to do things, right? Not everything is going to be a get request and there's a lot of theory about why should something be a get and a put and a post and so on and so forth. There's a couple of different types of HTTP requests that you can do. I won't go into too many details, but just know that, you know, the best practice is to create a put request instead of a get request for these types of things. The main reason being because put requests are basically to update a resource. So if you have a resource, so a resource is, for example, a to do item. If you know you're to do item and you just want to update it, then typically you do a put request. You know, it's a verb, right? I'm putting information to that resource, right? So that's what we're going to do here and the way we're going to do this is we're going to say to do's and then for slash. So this is going to be within the to do's, let's say tree of our path. We're going to say, you know, colon ID because this is going to be a parameter that we're going to be picking up. So this can be anything and then for slash, we're going to say complete. So this is going to be a put request that we're doing to mark a to do item of ID of whatever we're going to be sending in the URL to be complete. Again, requests, response, as usual. We're going to create a function. Now here we need to see how can we handle this to do item and mark it complete. So the first thing we want to do is we want to pick up the ID that's coming in through the URL parameters. The way you do this is we're going to say, we're going to create a new variable called ID and we're going to set it as a const again because we're not going to be updating that ID. And what we're going to do is we're going to say request the parameters, oops, sorry, params.id, params being short for parameters. And again, this is provided to us by the express framework. So now we're picking up the ID and what we want to do is now we want to load up the different to-dos in this file and get the one, the right one and update its complete attribute to be true. So the way we're going to do this is we're going to say FS dot again, read file, oops, sorry, read file. And we're going to say again in this store introduce dot JSON. Okay, we're going to want it as UTF-8 as usual and it's sending us the error and the data in the callback. Okay. And we've accidentally deleted a close parenthesis there. Okay, so all is good here. Now again, we're just going to copy and paste this error because it's going to be the same thing if we don't find it, which would be very strange in our case. We're just going to send this status code to 500 and sorry, something went wrong. Right. Now, the interesting thing is going to be again, we're going to copy this, const-dos is equal to JSON parse of the data. Now, what we want to do is we want to find the appropriate to-do list. And the way we're going to do that is to use this ID and get the to-do by the ID, right? If you remember here, we have a bunch of IDs, one, two, three. If we find the right one, then great. If we don't, we need to return a 404 error. So the way we're going to do this is we're going to just create another function inside of this handler and we're going to say const find to-do by ID is equal to a function. Right now we're just going to do this like that. So this is basically defining a new function in JavaScript. We're calling this function find to-do by ID. And right now we're not getting, accepting any parameters. We're going to change this in just a second and we have an empty function body. So this function is going to accept two parameters. It's going to accept the to-do lists and an ID that we're looking for in this to-do lists array. So what we're going to do is we're going to create a for loop. And the way you create, the way you create for loops or the simple way you do that in JavaScript is a four open parentheses and then you need to do three parameters. You need to set a iterator value. So this is basically a value that keeps track of what item are we on, right? So any list in most programming languages starts with what's called a index of zero. So the first item is the item number zero, let's say. And then it progresses by incrementing one each time, right? So let's keep track of the index in this case and we say let i short for index is equal to zero. And then we're going to say i is less than to-dos.length because what this does is it tells this list that it needs to finish sometime, right? It can't just go on forever. So as long as i, so this index counter, let's say, is less than the length of items inside the to-do list, we're good, right? We can continue to move forward. And then we need to also tell it how are we going to be incrementing these values, right? So we start at zero and we cannot go above the length of the number of items in the to-do list, but we also need to tell it by how much it needs to increment each time. So in this case, we're just going to say by, we know we need to increment by one. And the short form to write this is just to say plus plus, i plus plus. i plus plus in JavaScript means that we're going to be updating the value of i by one each time. Now, the body of this for loop is going to contain basically a little bit of logic, which is, and we're going to say if to-dos, and we're going to, you know, to-dos is the entire list, right? But we want to go one by one. We want to start with this one, then we're going to, we want to go to this one. And then finally we want to go to this one, right? So that's why this i is going to come in handy because this keeps track of which one are we going over. So we want to go into each item. And the way you go into each item is you open, open square brackets with the to-dos variable. Again, this is a list. You open square brackets and you say, okay, I want to go to the zeroth item, or I want to go to the first item, which is in actual fact the second item. Because remember it's always indexed with zero, so it's always one less. And, or I want to go to the third item, right? So this is the way you would access each individual item inside the list. So instead of just hard coding it to fix number, we're going to say just go into the ith element because this keeps changing, right? So if to-dos, the nth, or the ith, it's a bit difficult to pronounce. If the ith element of to-dos.id is equal to the id that's sent into the function, then what we're going to do is we're just going to return the index of this item, right? And it's going to stop the execution here. Any time you return the item, the execution stops inside of this function in this case, right? And if we don't find the element, then we need to return something else. In this case, we're just going to be returning a-1. And like that, we'll know that it hasn't found the element because basically it's impossible for this to return a-1 because it starts at zero. It goes up each time. So if we receive a-1 with this function, then we know it hasn't found this. And this is, by the way, a common practice in many functions in native JavaScript. Okay, so that's done. The next thing that we need to do is we need to find the actual index of this file using our function. So the way we do this is we're going to say to-do. To-do index is going to be find to-do by index. So we're going to pass in all of the to-dos in JSON format. If we just pass the string, this would work because, you know, again, we're iterating over an actual object, not a string. And we're expecting to receive the ID that we're capturing here, right? So again, ID. So it's passing this ID into the function, and this should basically, you know, find the actual to-do for us. So just to make sure that everything is working, let's just return response.json and let's just say to-dos. And we're going to be indexing into the to-dos index, right? To-do index, right? One thing we need to do is if... Sorry, I forgot to do this. If to-dos index is equal to minus one, then we haven't found it and we can already do this. We can return a response of status code 404 and send a text of sorry not found. Okay? And if it does find this, then we can... For now, we haven't finished, but we can just, you know, return the actual to-do item, right? So let's restart the server. Go back to our postman and let's just duplicate this tab and then say to-dos one. Okay, we have some sort of error. Oh yes, of course, because it's not a get, it's a put. And we still have an error. So let's figure out what's going on. Ah, yeah, of course. Of course, the URL was incorrect. Sorry not found one. Why is this happening, right? So we're saying we're accessing one, so it's working. This is working, but it's not working in the way we want it to. So we're trying to access to-do one and for some reason it's not finding it, right? So let's see what's happening. Okay, so we are receiving a parameter here and this parameter comes in the string form. So express always returns strings in these parameters. While here, our to-dos are coded as numbers. If you see, you know, if we change this now, this will work, but this is not what we're intending. I'm just doing this to show how strings and numbers are different in any programming language, quite frankly. If we go back here and we say one, this is now going to find a string. As you can see, it's founded, right? And the reason why it's founded is because here, you know, types are very, very important in programming languages. It's not the same thing to look for one as a string as it is to look for one as a number. And the way we're doing this here is we're doing a strict equals, a triple equals, which means it's comparing not only the actual value, but also the type of what we're sending here, right? So I'm going to go back here and delete this because I don't want this to be a string. And instead here, what we're going to do is we're going to say, we're going to parse this whatever we're sending here as, and we want it to be a number, right? So parse int and whatever we're sending is if this is a string, then we're going to try and turn it into a number, right? So anything, now as we're collecting here a string, and ultimately we're passing it into this function and we're converting the string to a number, this should work, right? So I'm going to restart the server. Go back to Postman. And now again, this should work and this should be represented as a number. Okay, great, excellent. Right, so this is working. Now the last thing we need to do is we just need to update this to-dos index. By the way, this can no longer be a const because we're actually updating it. So we need to say that it's a let now. Let is basically the same thing as a const but then it allows you to modify the content or the value of this, anything you're storing here. So to-dos.index.complete is equal to true, right? So we're updating the value of the complete key inside of each to-do to be complete. Now, the last thing that we need to do is we need to write the file. We need to update file here on disk, right? So the way we do this is we say fs.writefile. The first thing that we need to send again is the path store.todos.json. And then we just need to say, what are we going to be writing to this file? So the way we're going to do this is we're going to say json stringify to-dos. Okay, what is this doing? This is basically picking up the object that we have here in our application and we're turning this json object back to a string. The way we do this is because native file systems cannot really store a json. Json is an object that's parsed in memory. So whenever we store something, we typically have to store it as a string. So that's why we need to convert it back to string and that's where json.stringify comes in handy. Okay, and then the callback. So the writefile callback doesn't really return us anything here. We can just receive or access this callback function once we're done, right? So here once we're done, we can simply just return a response to the user and say json response. This is not really going to contain anything useful. We're just going to tell the user that the status was okay. So basically just indicating the user that we have successfully marked the to-do item as complete, right? So I'm going to go back here and as you can see right now, the to-do item number one is not complete. The complete is false. I'm going to quickly restart the server. Go back to here, launch this. It says status okay, which we can think that everything has gone correctly. And as you can see here, all of a sudden the to-do with item number one or ID number one is complete. So everything is working. Excellent. So now if we go back here and call to-dos again, the list of to-dos we can see, you know, as we saw before, the item with ID number one is complete, which is great. Now we can, you know, take the opportunity to create an improvement in our to-dos endpoint. So let's go back to our endpoint that deals with all of the to-dos, the list of to-dos. And here what we can do is we can basically filter out all of the complete ones, right? Or we can leave it optional for the user. Like does the user want all of the to-dos or do they only want the complete ones? So the way we're going to do this is we're going to pick up a query parameter that the user can send. So we're going to say show only complete is going to be equal to request query.show complete, okay? So what we're doing here is we're allowing the user to send us a query parameter, which I'll show you in just a second what it means, called show complete. And if there's anything in this query parameter, then we will just filter out all of the... Sorry, this should be actually show pending. Show pending, right? I think that's the more intuitive way of representing to-do lists, right? So show only pending items, okay. Right, so how do we implement this? So the way we're going to do this is if show pending, sorry, show pending is not strictly equal to the string of one, then we're just going to send back everything, right? So we're going to just cut, we'll cut and paste this there. And then we're going to say else, sorry, else and then here we're going to filter them out, right? So what are we doing here? Okay, let's take a step back. We're going to be accepting a show pending query parameter. So if this is going to be anything other than one, so it can be either not existing, so the user can maybe just not send us this or it can be anything other than one, we're just going to send the full list back. However, if the user sends us the show pending query parameter equal to one, then we're just going to filter out everything that's complete and just leave out the pending ones, right? So what I'm going to do is I'm going to copy and paste this code. But here, instead of sending all of the to-dos, what I'm going to do is I'm going to filter them. So I'm going to say to-dos.filter and here what I'm going to do is the filter function, it iterates over each item in the list. So in this case to-dos, I'm just going to call it in its short form, just say t. And here in the filtering logic, I'm going to say return if t.complete is equal to false. So this is the logic that I'm going to be using to basically see if t.complete is false. Then I want this to be included here. If it's true, then it's not going to be included by the filter function, right? So let's just see if this is running. I'm going to just quickly restart the server. I'm going to go back here and then in to-dos, I'm going to add the query parameter. So it's called show pending. I'm going to copy and paste it here is equal to one. Excellent. As we can see, item number one has been removed from the list because we only want the pending ones, so the ones that are complete equal to false. Now, if we say pending equal to zero, it's included again, or if we just downright just not include this query parameter, it's also included, right? Excellent. Everything is working. Okay. So the last endpoint that I would like to create in this project is one where we can actually add a to-do list. So typically for adding items, you use a post request. That's exactly what we're going to do, and we're going to post to to-do because it's an individual to-do that we're creating. And we're going to say request, response as usual, open up here, and we're going to process the actual request, the post request to create a to-do item. So the first thing we want to do is actually before we start, we need to make a couple of small modifications to our express application. So at the very top, when you declare your application, let's, we need to make express use certain middleware that it comes with, okay? So explain this in just a second. For the time being, what we're going to do is we're going to say app.use, express.json, and we're going to say app.use, express.url encoded, open parentheses, open curly braces, extended, and we're going to say colon true. Okay. So what are we doing here? I'm not going to go into too much detail. You can just copy and paste this. But basically, post requests come in different shapes and sizes. And the way we're going to be using a post request is more of a, you know, JSON API type way, which is, you know, you need to configure express to kind of be able to understand that it's in that type or that kind of, you know, format. So these two lines just tell express, okay, we want to parse certain post requests as they would be a typical JSON API, right? I'm not going to go into too much detail. Just copy and paste this code. Okay. So now that we've done that, we can continue writing our application. And what we're going to do is we're going to say if, you know, their request doesn't come in with the expected, you know, payload that we require to create a new to-do list, then we need to tell the user that, you know, they've basically sent us the wrong request. So if not request. So that's why we're adding this, you know, bang here. It's called a bang exclamation marker and coding. It's called bang. If bang request dot body dot name. So if name is not inside of the body of the request, then we just need to return response dot status a 400. So this is something that the user has sent badly to us. And then we're going to send a message of missing name. So a missing name of the to-do item. Okay. If that is how we're present, the code is not going to enter here and we're going to continue. And what we're going to do is fs read file. Read file. Again, same location store to-dos dot JSON. Again, utf 8. Again, error data. You already know this. Just going to copy and paste the error code for managing. Sorry. This is if error. Right. We can move this inside. Okay. So now that we have data again, we need to also process the data by doing JSON dot parse of the data. Okay. Great. Now, we have the list loaded as a JSON object and we need to add an item to this list. So the way we need to add this is, you know, obviously we need a new ID for this item that we're going to be assigning ourselves. And, you know, our application is going to be assigning. So the way we're going to do this is we're going to say, we're going to pick up what's the maximum ID that's already present in this list, right? In this case, it's going to be three. So in order to do that, we're going to say max ID is going to be equal to math. We're going to be using the math, the built-in math library inside of JavaScript. We're going to say get the, sorry, max and apply because it's going to be, you know, a mapping of the max function that we're running over the list of items. So again, just we're going to say math, to-dos dot map, T. I'll explain this in just a second. Return T dot ID. Okay. Okay. So what are we doing here? We're using the math, max. As you know, you can probably your intuition is saying, okay, we're kind of mapping the max function over a list of to-dos. But you know, since to-dos is not a simple object with just numbers in it, it has a bit of structure to it. We need to tell this math, max library how to, or which values are we kind of figuring out the max for, right? And we want to figure out the max for the to-do items ID. And in order to do that, we just, oh, sorry. This is incorrect. This is not maps. It should be map. We're mapping this math, max function over the IDs of individual to-do lists, to-do items. Sorry. Okay. So now we have the max ID. So the last thing we want to do is we want to say to-dos the push, which is the JavaScript function to just add a new item to the list. And here we're going to say the ID is the max ID plus one, because we want to increment it by one. The complete is going to be false because every time we add a new item, the completion is going to be false. And the name is going to be the request, sorry, request.body.name. There we go. Okay. So the last thing we need to do is we need to update this file. So again, I'm just going to copy and paste this code here because it's going to be exactly the same. And this should be it. This should be up and running. Okay, great. So let's test this out. Again, it's a post to-do, and it requires a name in the post payload. So I'm going to just reset my server. I'm going to go back into postman. I'm going to duplicate this request. I'm going to change it to post. It needs to be a to-do. And in the body, we need to set it to a raw JSON. And here we're just going to say name is, I don't know, complete the JS course. Great. Let's send this. And it says status was okay. Let's go back to our to-dos, make a call, and see what's happening. And sure enough, we have a fourth and new to-do list, completion false, complete the JS course. And as we're approaching the end of the programming part of this course, we're about to start to do the AWS uploading part. So what we're going to do is we're going to complete the to-do item of four. Go back here, see the completion is true. Excellent. So we have successfully completed the programming part of this course. Now we're going to wrap things up and start to see how we can deploy this application to AWS using Fargate. And welcome back to the second part of this course where we will basically deploy our application into AWS Fargate. So as I mentioned before, Fargate is a solution developed by AWS, which allows you to run your applications on the cloud without having to manage the resources or the underlying resources that host your application. So typically, when you deploy an application, you have to provision all of the resources, so provision the virtual machines, install all of the different dependencies that you need, so on and so forth. And more frequently that's being automated using Docker and AWS Fargate is another way to do that. But the really interesting thing about AWS Fargate is it completely takes away all of the management of the underlying infrastructure. So typically, as I said before, you would need to provision a cluster and manage the resources on that cluster and just make sure that you don't have too many resources because then you're paying too much for what you need or you have too little resources and hence that could be affecting the performance of your application. So AWS Fargate is a solution where you just upload the image of your Docker with your application inside it and then AWS Fargate basically takes care of the rest, right? So it's a really, really convenient solution. It's very cost effective. You won't incur into any costs during the course of this course. The downside to AWS Fargate is that it's a little finicky to set up if you don't know what you're doing, right? But that's the whole purpose of the second part of this course is we're going to go through together into actually configuring AWS Fargate and get it up and running. So without further ado, let's get started. So I'm here back in our project that we finished up coding in the last section. And so now the first thing that we need to do in order to start the process of getting it pushed to AWS Fargate is to Dockerize our app. How do we do that? First of all, we need to install Docker on our machine if we haven't done so already. So we won't spend too much time into explaining how do you install Docker. You have this website docs.docker.com where you can read all about how to install Docker on your individual platform. For Mac, it's very simple. You just have to download and drag the application to the applications folder as you do with pretty much anything on Mac. I believe for Linux it's fairly simple too and Windows shouldn't be too difficult either. In any case, when you have Docker installed you should be able to open up the Docker application. Make sure it's running before you do anything. So here I have it open. So that's great. Now I can go back to the Visual Studio Code project and we can start Dockerizing our application. So the first thing you need to do whenever you're Dockerizing an application is you need to create a new file and it has to be called exactly Dockerfile. And the D has to be capital. So it's Dockerfile without anything else. So we click enter to create the file and now we can proceed to write our Dockerfile. Okay, so what is a Dockerfile? A Dockerfile is essentially a set of instructions for Docker in order for Docker to be able to recreate the environment your application needs in order to work. So it's fairly simple to do and we're going to go right now and kind of just write up the Dockerfile from scratch. It only has a couple of like 10 lines of code or something. It's not really code. It's just like basic Docker instructions. So the first thing any Dockerfile needs is it needs to know what operating system it's running on or what's kind of equivalent is what base image are we using? So base image is a kind of template image for Docker to kind of pull and use that, right? So a base image could be a distribution of Linux or a version of Linux or it can be any kind of already pre-built Docker image that can then host the application. So what we're going to do is we're going to write from node colon 12 and this tells Docker that we're going to be using the pre-built Docker image called node colon 12 and this basically says it's an arbitrary version of Linux. I'm not really entirely sure actually what version of Linux it is with node version 12 installed on it. So this single line of code in the Dockerfile abstracts for us a bunch of different things that we would otherwise have to do. So this is super convenient. The next thing we're going to do is we're going to declare our workdir. So this is done by typing workdir and I'm just simply going to say forward slash app. So this is basically similar to just creating an app directory inside of our container and setting it as our working directory. Next thing I'm going to do is I'm going to set the environment variable and say node n is equal to production. Sorry. And basically what this does is it forces the environment variable node m to be set to production. This is just a common thing I do whenever in a node application just so that node knows that it's a production environment. Okay. So the next thing I'm going to do is I'm going to copy package star dot JSON to dot forward slash. What does this command do? It basically copies both the package and the package log files into the working directory. So forward slash app. We need these to be able to npm install all of our dependencies which is going to be the next thing that we do. So we need to tell Docker to run a command of npm install. Okay. So by this point Docker will execute npm install and obviously npm is already installed inside of the container because we pulled from the base image of node and obviously node being the base image of node already has node and npm installed on it. So this is great. The next thing we need to do is we need to copy all of the source files and the way you do this is you write copy dot space dot. Okay. So this is like super strange but it's actually very, very intuitive. So what we're telling Docker to do is we're copying everything from the current project directory. So everything that's inside here and we're pasting it to the working directory. So by typing in the instruction worker forward slash app we're basically creating this directory and sending it to our working directory inside of the container. So what we're telling Docker here to do is copy everything from the current directory on the project to the current directory in the container, right? So next thing we need to do is we need to run another command which is npm install dash g pm2. What does this command do? It basically installs globally inside of the container a library called pm2. pm2 is basically a library that's much better to execute your node application in a production scenario. It's not really a good practice in production to do node index.js and kind of have the application run that way. Reason being is it's not the most efficient way to do it and also if your app crashes then the whole process crashes and just crashes, right? And there's no process realizing that the app has crashed and trying to get it back up and running again. And that's exactly what pm2 does for us, right? So once that's done we need to expose the port 3000 because that's the port that our application is running on and then finally we need to run a command which is pm2 runtime and then index.js. So this would be the equivalent of in the terminal saying pm2 runtime and index.js, right? And this is done by just typing in cmd and then in an array format typing in the different... well, the command and the arguments to pm2, right? And this is basically it, right? So I'm gonna save this and we need to do one more thing before we actually build the Docker image and that is to create another new file and call it .dockerignore. What are we going to put inside of this file? Basically we're just gonna type in node modules and that's it. Save it and that's it. What is this doing? What is this .dockerignore file doing? Well, basically, you know, in this step we're telling Docker to copy everything from the current file to the appropriate working directory inside of the container. However, we do not want to copy the node modules folder from our project directory. Why is that? Well, because, first of all, in my case, I'm running on a Mac and when I installed all of the node modules for my project on my machine, basically what NPM and Node does is it installs some of the version, some of the libraries are going to be tailor-made for your operating system. And obviously that's a problem when you're porting your application to another operating system, then you will inevitably break things. So the common best practice in the industry is to every time you're uploading an application to Docker you just build or you do the NPM install from scratch. So essentially you're kind of like building the application from scratch on the environment it's going to be working on. So when we run NPM install on this Linux container, then NPM will make sure that it's installing the right versions for Linux every time. And then we can just simply copy all of the other source files. So that means this index.js, the store, and the tattoos.json and everything else. So we're going to be copying everything except for node modules. That's where the .dockerignore file comes in handy because here we can just list everything we want to ignore in the copy step. Excellent. So now with that done, basically we can go ahead and start to upload this to our AWS account. Okay, so I've opened up my AWS account and the first thing that we need to search here is something called ECR. So this stands for Elastic Container Registry. Here it is. And we need to create a new registry, a container registry which will hold our Docker image. So the way we do this is we just click here and create new repository. Just 01 and leave all of the other settings default and that's it. So here we've created a new repository and now if I click into it and you can see this button view push commands and these are all of the different instructions that I need to carry out in order to push my Docker image to AWS ECR. So I'm going to just here, I have a handy icon to just copy all of the commands and I'm going to go ahead and do that right now. Okay, so I have my terminal open and I'm just going to now sequentially paste all of the different commands into the eternal. So this first command is to log into our AWS ECR account. Login succeeded. I'm going to go back, copy the second one which is a Docker build. Here we're essentially just building our Docker image out of the project and all of the different files. Okay, so the build process is complete. It might take a little while. Now the next thing we need to do is we need to tag our Docker image on our local computer with an address to where we're going to be uploading our Docker image. So let's just do that. This is going to take very little. And the last thing we need to do is we need to actually after tagging it to push our container to ECR. So let's do that right now. Okay, so that took a little while in my case, but it's finished, which is great. So now if we go back here to our repository and we refresh, then we'll see that we have a new Docker image. So this is great. Now, the next thing that we need to do is we need to actually start to set up our Elastic Container Service cluster. So how do we do that? Let's now search for ECS, which stands for Elastic Container Service. Okay, so now we're in the ECS page where we can start creating our AWS Fargate cluster. So the first thing we need to do is now that we have our Docker image pushed to the Elastic Container repository, we can go ahead and create a cluster. You will probably not see anything here. I've been doing a couple of tests, and that's why you see some other clusters here. But let's create one from scratch. So we're going to create a cluster, make it networking-only, powered by AWS Fargate, next step. And here all we have to do is we need to assign a name. So I'm going to call it cluster.js01. That's kind of the short code I used for this course. We want to make sure that we don't click on create a new VPC. Reason being is that AWS already provisions a default VPC that we're going to be using when you open up an account. So that's why we're not going to be creating one. So let's go ahead and click create, view cluster. Now we can see that we have a cluster created. Now a cluster is essentially kind of what the name suggests. It's a grouping of different compute resources that we will be using to host our application. In this case, for the purpose of this course, we're just going to have one set of compute resources, which AWS calls tasks to run our application. So you can see here a tab called tasks. This is the tab that we're going to go to to monitor the compute resources that we have running our application. But before we do that, we need to create a task definition because a task definition is again what the name suggests is a definition of these compute resources that are going to be running our application. So let's go into task definitions. And here we have, I already have a couple of tasks done, but let's create one from scratch again. We need to make sure it's a Fargate task. Click next, give it a name. So this will be task def js01, for example, in my case. And then basically all of the other kind of values here are going to be defaults. We're not going to create a task role. We're going to leave all of these defaults. And then here, very important, for the purpose of this course again, we're going to select the smallest values. And this is kind of the section where we define the amount of memory and the amount of CPU power that we want for our instance that's going to be running our application. So again, here it's called tasks. A task is basically a defined set of compute resources which we're defining here that are going to be running our application. We also need to define the container that we're going to be spinning up inside of this task. So let's go ahead and click add container. And here is where we're going to be, you know, linking the container that we just uploaded to the Elastic Container Registry. So let's just call it container to do. Or sorry, I have a typo here. Js01 maybe. It doesn't really matter. And now here we need to copy the URL that we can use to address the container image that we just opened or just uploaded. So what I'm going to do is I'm going to open up a new tab and I'm going to go to ECR. So the Elastic Container Registry. And once I'm inside, I'm going to basically go to the repository that we just created where we pushed to our image, Js01. Latest. And here we have the image URI which we can just copy. Go back to the previous tab and paste it in here. This we can keep the default soft limit of 128 megs for the memory limit. And here in the port map this is very, very important that we enter 3000 in the TCP port mapping. Why is this? Well, if you recall, if we go back to our application, we're essentially telling Express to listen to inbound traffic on the port 3000. And this is also why in the Docker file we exposed the port 3000. So traffic is going to be coming into the container on port 3000 and then inside of the container, Express is going to be listening to the port 3000. So this is why we need to map and make sure that our task definition opens up port 3000 for the container. And all of the other values we can just skip, leave blank and click add. Okay, once that's done all of the rest of the values we can just leave defaults and we can create the task definition. Excellent, so this is created. We can go back to the cluster and the next thing we want to do is now we need to go to the cluster we created previously, so it's cluster.js 01. And here we under the services tab we need to create a new service. So a new service is basically linking the cluster to the task definition that we just created. And when we start the service, the service is essentially the thing that's going to be monitoring and making sure that all of our tasks are healthy and up and running, right? So let's create a service. Let's select Fargate as the service type. Under task definition, let's select the task definition that we just created, so task.js 01, my case. Let's give this service a name, so service.js 01. Number of tasks, let's keep it to one. And here we have a set of minimum health percent and maximum percent, 100 and 200. These are just defaults, leave them as they are. These are kind of made for auto-scaling purposes. We're not really going to play with them in this course. So just leave them default. And then we can hit Next. And here we need to select the VPC. So this is the default VPC that AWS has provisioned. And then under subnets, we need to just select all of the subnets, right? The amount of subnets that you have may vary. And that depends on how many subnets AWS has provisioned under your account as default. And that kind of depends also on the region that you're using. I'm using the North Virginia region, but this doesn't really matter what region you're using. And then, next, it's extremely important that you edit this security group. So when we edit it, we want to create a new security group. And here we want to make sure that we select Custom TPC. Sorry, Custom TCP. And enter the port 3000. Again, this is the port that our container and our application is using. And the source accepts traffic from anywhere, basically. So we want to hit Save. Autosign public IP enabled. And then, also very important, we want to make sure that we select a application load balancer under load balancer type. Why is this? And by the way, when you select this, this input field will pop up and we need to change this value to something like 30, 30 being 30 seconds. Now, what is all of this application load balancer and health check raise period? Well, as I mentioned already previously, AWS Fargate is a AWS product that basically enables you to autoscale your application. And what that means is that if you have a little amount of traffic, then you will likely just have one task or one set of compute resources running your application. But as you get more traffic and as those compute resources are being saturated, AWS will automatically spin up new tasks or new set of compute resources to manage that workload, right? And the only way that you can have a single entry point being, let's say, for example, a domain name and have that load or that bulk of traffic being distributed equally to the different compute resources or tasks that you may have spun up, the only way to do that is if you use a application load balancer. So in essence, the traffic will be directed to a application load balancer and this application load balancer will be configured in such a way that it distributes traffic equally to all of the compute resources that AWS Fargate spins up for you. Okay. And what is this value of 30 seconds here? Well, a application load balancer has what's called a health check. And a health check is basically just a periodic ping it does to your website every X amount of seconds, and it evaluates if your application is responding a good status code. So basically a status code of 200. Now, sometimes as your application is still spinning up, it might not be fully responsive. So this health check grace period is basically telling, okay, if you're not expecting the right kind of HTTP status code, just wait for 30 seconds before you deem it to be unhealthy until AWS Fargate or ECS in this case to kind of restart that task. So that's all of that that's happening here. Now under load balancer name, you will likely not have anything. You will have this empty and AWS will be prompting to you that you need to create a load balancer. So go and click on that link. Meanwhile, I'm going to go to the same page that you will be directed to. And we will create a new application load balancer from scratch. Okay, so here I am in the application load balancer page, which you will be directed to. Again, you won't have anything here. This is just a previous test I made. So create a new load balancer and make sure you select the HTTP or HTTPS load balancer hit create. Here we need to give it a name. So I'm going to call it application load balancer.JSR1. We need to make sure it's internet facing IPv4 and the listener is set to HTTP port 80. Now, why are we mapping port 80 on the application load balancer? Well, as I said before, the application load balancer is going to be the internet facing side of things. So it needs to listen to the default port that, you know, every website uses. So right now I'm accessing the AWS console through port 80. If I were to open up Google, you know, again, any typical website is hosted on port 80. And that's just the default, right? So we're going to be listening into incoming traffic from the internet on port 80. Next, we're going to just, you know, select the default VPC and select all the subnets as we did before. And then we're going to hit next. We're going to skip the security settings. And here we need to create a new security group. So we're just going to leave the default name. We're going to set custom TCP. And we're going to, you know, allow it to listen to traffic on port 80 from anywhere. We're going to hit next. And here, very importantly, we're going to configure the target group. What is a target group? A target group is a kind of, as the name suggests, it's a way of, for the application load balancer to understand what is it targeting. So what is it going to be forwarding traffic to? And so naturally, we need to create a target group and link it to the, all of the different tasks that are going to be created by AWS Fargate or ACS. So let's create a name for this. This is going to be TG for a target group and just called jaser one. We need to make sure it's an IP based target group. And then we can leave the rest of the values default. Now this part is very important. In my case, I need to leave this default. But in your case, it may vary. If you follow the course, the coding part of the course, exactly as I've done, then you will also have to leave a default. So basically, we need to enter the path to our application for whatever, you know, endpoint that we created that returns this low world. Okay. So why do we have to do this? Well, this health check is going to, as I said before, ping this path. So, you know, it's going to ping this controller every set amount of seconds and kind of evaluate what the status code for the responses. If the status code is anything other than a successful status code, so basically a 200 or it takes too long to respond, then it's going to tell ECS and AWS Fargate that, you know, the application is not responding and it's going to tell it to restart that task. That's something we do not want if our application is in fact running healthy. So please make sure that you enter here the path of the equivalent controller or the HTTP handler that you implemented with a hello world, you know, response here. Okay. Next, register a task. This we're going to leave default review and hit create. Excellent. So we just created the application load balancer called JS01. We're going to go back here to the step where we were creating the service and we're going to just refresh this list and select the newly created a application load balancer JS01. Okay. The container to load balance part. Here we can see that we have the container JS01 already loaded for us. We're going to add it to the load balancer and here while we're at it, this is also very important that we configure this correctly. So the listing port needs to be 80 HTTP. So this is basically the inbound traffic to the load balancer is going to be on port 80 and then the target group is going to be this target group JS01 that we created. So basically this is how we're linking this service to the target group I was just talking about, right? So this is how we're telling the application load balancer that it needs to forward all of the traffic that it receives to the service that we're creating which is also going to host our application inside of our container. Okay. Next step. We're going to skip this part of auto scaling although this is a really nice feature of AWS Fargate. We're not really going to be using it for this course. We're going to hit next and create. Okay. So our service is created. Now, as I refresh this, you will start to see that we are going to start to provision resources for application. Here we are. AWS Fargate is provisioning resources. The desired state is going to be running. The last known state is provisioning. So this will take maybe a minute or two. So when it's done, I'll come back. Okay. And our task is running. So let's click into the task. And here, if we open up this dialog, we can go and see the logs in CloudWatch and just for demonstration purposes, we'll be able to see that our application has started correctly. So here we are, the logs. This is the log that we all see in our console when we start the application. Application is running on HTTP local host 3000. Now, this is obviously local host from within the container, but in actual fact, our application is already internet and public facing. So let's go back here. And we can see that under network, we have been assigned a public IP. So let's copy this, enter it into our browser, and add the port 3000 with a colon here. And successfully, we can see that our application is in fact running. This is the hello world for our application. So this is excellent. We're up and running. And now if we go back to the load balancer, here in the load balancer, we can also see that it has been assigned a DNS name. So let's copy this and go to our application and enter it. And here we can see that our application is also accessible through the load balancer. So this is great because now if I go into first slash to do's, we can see the initial set of to do's that we created, right? So this is all nice and working. Our application is live. It's on the public internet. And the last thing we can do optionally is to set up a domain name so that instead of accessing, you know, our application through the IP address I just entered or this very, very long, you know, address for the load balancer, it can be accessed through a custom domain name that we can buy. Okay, so now that we have everything up and running, the last and optional step that we have that we can do is we can configure our app to be accessible through a custom domain name. So instead of having to type as I did previously, instead of having to type this very long URL which is provided to us by AWS and we cannot really change it. But that's not really an issue because typically you do not access the app over this URL. Instead, you buy a custom domain name, whichever one you want, and you redirect traffic from that domain name to the load balancer. And this is completely then transparent to the user. The user doesn't really know that their request is being forwarded to this application load balancer and they never see this URL, in fact. So let's go ahead and do that. The AWS product that we use to buy and map domain names is called Route 53. So I'm gonna look for Route 53 here in the search box. Then here you can see that in my case I have two different domain names that I've already bought under this account. So I'm going to click here to access my domain names. And this is the list of my domain names. Now, if you don't have any domain names here, you can register a new domain name by accessing or by clicking here in registered domain names. And here you can just click register domain and kind of search for a domain name and buy it from here directly. So I'm going to go back to the dashboard and from here I'm going to click onto the hosted zones. Again, to see the list of my domain names I'm going to click on the JavaScript.academy. And here you can see that by default AWS creates certain mappings for your domain name, right? We're not going to go into too much detail on what these are. Instead, we just want to create a new record and we're going to keep the simple routing in place. And here we can choose to either map the root domain name. So if we leave this blank, we would be mapping the JavaScript.academy domain to our load balancer. Instead, what I'm going to do is I'm going to map the subdomain of JS01 to my load balancer. So I'm going to enter JS01. This can be whatever you want it to be. It can be 3Ws, for example. It can be whatever you want, right? And I'm going to switch on the alias because this then will allow us to map or route the traffic to a alias to application and the classic load balancer. This is exactly what we want. And now we have to choose the region where our application load balancer is hosted. In my case, this is North Virginia. So it would be US East 1, North Virginia. And then finally here we choose which load balancer to route it to. So in my case, it's the one I just created with you guys. It's ALBJS01. And basically this is it, right? I'm going to create the record. And basically that's it. The record is created and the mapping is done. So now this may not take effect immediately. So if you copy and paste this to your browser and it doesn't work, you just need to wait a bit. But more often than not, it works immediately. So as you can see now, my application load balancer and hence my express application inside of the AWS Fargate container is accessible through my custom domain name. So it's js.js01.javascript.academy. And in your case, you can just buy any old domain name and map any subdomain or in fact, the entire domain name. So if I left the js01 part blank, I could have mapped the entire domain name, the javascript.academy to the application load balancer and hence my application. So now if I go to forward slash to dos, oops, sorry, I forgot. I deleted the subdomain domain. So now if I go to the subdomain and forward slash to dos, as expected, the application is up and running correctly. Great. So and as you can see, this is, as I said before, totally transparent to the user, right? Here from here, we cannot see that we're in fact, forwarding the traffic to our application load balancer. Right. So this concludes the quick course on backend app development with Node.js and hosting your backend application using AWS Fargate. I hope you really enjoyed the course. And if you did, please leave an honest review on the course on Udemy. And if you enjoyed the course and you enjoyed backend development with Node.js and AWS Fargate, then stay tuned because I'm going to be releasing more advanced courses where we will learn how to create production-grade applications where we store information in AWS DynamoDB. So it's AWS database, which is used to store information instead of storing it on the physical hard drive as we're doing in this course. And we will learn many more advanced ways of just basically writing more production-grade applications. So stay tuned for that if you like the course. And for now, thank you very much for taking this free course. And I hope to see you guys in the next one. Take care.