Transcript for:
Comprehensive Overview of Node.js

[Music] node.js or node is an open source and cross-platform runtime environment for executing JavaScript code outside of a browser quite often we use node to build backend Services also called apis or application programming interfaces these are the services that power our client applications like a web app running inside of a web browser or a mobile app running on a mobile device these client apps are simply what the user sees and interacts with they're just a surface they need to talk to some Services sitting on the server or in the cloud to store data send emails or push notifications kick off workflows and so on node is ideal for building highly scalable data intensive and realtime backend services that power our client applications now you might ask but MOS there are other tools and Frameworks out there for building backend services such as h.net rails Django and so on so what's so special about node well node is easy to get started and can be used for prototyping and Agile development but it can also be used for building super fast and highly scalable Services it's used in production by large companies such as PayPal Uber Netflix Walmart and so on in fact at PayPal they rebuilt one of their Java and spring based applications using node and they found that the node application was built twice as fast with fewer people in 33% fewer lines of code and 40% fewer files and more importantly they double the number of requests sered per second while decreasing the average response time by 35% so note is an excellent choice for building highly scalable services another reason for using node is that in node applications we use JavaScript so if you're a front-end developer and know JavaScript you can reuse your JavaScript skills and transition to a full stack developer and get a better job with better pay you don't have to learn a new programming language also because you can use JavaScript both on the front end and on the back end your source code will be cleaner and more consistent so you will use the same naming conventions the same tool and the same best practices and finally another reason for using node is that it has the largest ecosystem of Open Source libraries available to you so for pretty much any features or building blocks you want to add to your application there is some free open-source Library out there that you can use so you don't have to build these building blocks from scratch and instead you can focus on the core of your application next we're going to look at the architecture of node so in the last video you learned that node is a runtime environment for executing JavaScript code but what is a runtime environment really well before node we use JavaScript only to build applications that run inside of a browser so every browser out there has what we call a JavaScript engine that takes our JavaScript code and converts it to code that a computer can understand for example microsof oft Edge uses chakra Firefox uses spider monkey and chrome uses V8 and it's because of these varieties of engines that sometimes JavaScript code can behave differently in one browser or another now a browser provides a runtime environment for JavaScript code for example you probably know that in browsers we have the window or the document object these objects allow us to work with the environment in which our code is running now after 2009 the only way to execute JavaScript code was inside of a browser in 2009 Ryan doll the creator of node came up with a brilliant idea he thought it would be great to execute JavaScript outside of a browser so he took Google's V8 engine which is the fastest JavaScript engine out there and embedded it inside a C++ program and called that program node so similar to a browser node is a runtime environment for JavaScript code it contains a JavaScript engine that can execute our JavaScript code but it also has certain objects that provide an environment for our JavaScript code but these objects are different from the environment objects we have in browsers for example we don't have the document object instead we have other objects that give us more interesting capabilities for example we can work with the file system listen for requests on a given port and so on we can't do stuff like that inside of a browser right so in essence node is a program that includes the va8 JavaScript engine plus some additional modules that give us capabilities not available inside browsers we can work with the file system or the network and so on both Chrome and node share the same JavaScript engine but they provide different runtime environments for JavaScript now I've seen people comparing node to C or Ruby or some other programming languages but these comparisons are fundamentally wrong because node is not a programming language it's like comparing a car with an apple by the same token note should not be compared with Frameworks such as as.net or rails or Jango and so on these are Frameworks for building web applications Noe is not a framework it's a runtime environment for executing JavaScript code next we're going to look look at how node works so earlier I mentioned that node applications are highly scalable and this is because of the non-blocking or asynchronous nature of node what do I mean by asynchronous let me give you a metaphor imagine you go to a restaurant a waiter comes to your table takes your order and gives it to the kitchen then they move on to serve another table while the chef is preparing your meal meal so the same person can serve many different tables they don't have to wait for the chef to cook one meal before they serve another table this is what we call non-blocking or asynchronous architecture and this is how node applications work the waiter is like a thread allocated to handle a request so a single thread is used to handle multiple requests in contrast to non-blocking or asynchronous architecture we have have blocking or synchronous architecture let's see how that works so back to our restaurant example imagine you go to another restaurant and in this restaurant a waiter is allocated to you they take your order and give it to the kitchen now they're sitting in the kitchen waiting for the chef to prepare your meal at this time they're not doing anything else they're just waiting they're not going to take an order from another table until your meal is ready this is what we call blocking or synchronous architecture and that's how applications built with Frameworks like as.net or rails work out of the box so when we receive a request on the server a thread is allocated to handle that request as part of handling that request it is likely that we're going to query a database and as you know sometimes it may take a little while until the result is ready when the database is executing the query that thread is sitting there waiting it can't be used to serve another client so we need a new thread to serve another client now imagine what would happen if we have a large number of concurrent clients at some point we're going to run out of threads to serve these clients so new clients have to wait until free threads are available or if we don't want them to wait we need to add more Hardware so with this kind of architecture we are not utilizing our resources efficiently this is the problem with blocking or synchron architecture and as I explained that's how applications built with Frameworks like as.net work by default of course in as.net it is possible to use asynchronous architecture but you will have to do extra work for that in contrast node applications are asynchronous by default so you don't have to do anything extra in node we have a single thread to handle all requests when a request arrives that single thread is used to handle that request if we need to query a database our thread doesn't have to wait for the database to return the data while the database is executing our query that thread will be used to serve another client when the database prepares the result it puts a message in what we call an event cue node is continuously monitoring this queue in the background when it finds an event in this queue it will take it out and process it this kind of architecture makes node ideal for building applications that include a lot of disk or network access we can serve more clients without the need to throw in more hardware and that's why node applications are highly scalable in contrast node should not be used for CP intensive applications like a video encoding or an image manipulation service in this kind of applications we have a lot of calculations that should be done by CPU and few operations that touch the file system or the network since node applications are single threaded when performing the calculations to serve one client other clients have to wait and that's why node should not be used for CPU intensive applications it should only be used for building data intensive and realtime applications okay enough Theory next I'm going to show you how to install node and build your first node application in this lecture I'm going to show you how to install node if you're on windows open up command prompt if you're on Mac or Linux open up the terminal first let's see if you already have node on your machine or not so run node space Das Dash version you can see on this machine I'm running node version 6110.3 this is an earlier version of node the latest stable version is version eight now on your machine chances are you may not have node or you might have an earlier version either way I want you to install the latest version of node so open up your browser and head over to nodejs.org on this homepage you can see we have two versions for Note One is the latest stable version which is recommended for most users at the time of recording this video that's version 8.9.1 and there's always a newer version which is experimental and it might not be stable so I want you to install the latest stable version also take into account that in the future when you're watching this video chances are the latest stable version might be newer if you're worried that this course is going to get outdated don't worry because in this course we're going to focus on the fundamentals so I'm going to work with the core modules of node these core modules are stable they have been there for a long time so the code that we're going to write in this course will continue to work with the future versions of node once you master the fundamentals you can always learn about the new features that come in every version by looking at the change lock so let's not worry about the fancy new features in node and focus on the fundamentals so let's go ahead and install the latest staple version we can see here I get a package we run it it's an installer take a look very simple just continue continue continue install we need to enter our password and the installation is complete it took only a few seconds so now back in the terminal let's run node-- version one more time you can see I upgraded my node to version 8.9.1 next we're going to build our first node application all right now we're ready to build our first node application so I'm going to create a new folder call it first app let's go to this folder now I'm going to open this folder inside of Visual Studio code which is my preferred code editor so code period so this is Visual Studio code code or vs code it's a free powerful editor but you can use any editors that you prefer you can use Sublime you can use atom or any other editors so here in this folder I'm going to add a new file app.js in this file we can write regular JavaScript just like the JavaScript that we write for the browsers so I'm going to define a function say hello that takes a parameter name and simp simply logs a message on the console so hello plus name and then we can call this function like this msh now to execute this code we're going to go back to the terminal and run node and pass the name of the file as an argument so app.js so node as I told you before is a C++ program it includes Chrome's V8 JavaScript engine so this app. this file that we're going to pass to node node is going to give it to V8 for execution so you can see we got hello MH on the console now let me show you something so back in vs code I'm going to temporarily comment out this line and do a console.log of window let's see what happens so back in the terminal let's run node app.js we got an exception window is not defined so as I told you before in node we don't have the window or document objects these are part of the runtime environment that we get with browsers in node we have other objects to work with files with the operating system with the network and so on and that's what you're going to learn about in the next section I hope you enjoy this section and thank you for watching in this section we're going to look at the module system in notes you will learn what modules are why we need them and how they work throughout this section we'll explore a few of the modules built into the core of node such as operating system file system events and HTTP you will also learn how to create your own modules now let's get started so in the last section we use this console the log function to lock something on the console now this console object is what we call a global object so it's part of the global scope which means we can access it anywhere in any files we have a bunch of other objects and functions that are also globally available in node for example we have set timeout which you have probably seen before we use this to call a function after a delay like 1 second 2 second whatever so this is just just part of the standard JavaScript we can use this on the client we can use this inside of a browser or inside of node we also have clear timeout similarly we have set interval which we use to repeatedly call a function after a given delay we also have clear interval which we use to stop that function from being called repeatedly so these are the global objects in JavaScript now in node we have a couple other Global objects that you're going to learn about later in the section now in browsers we have this window object that represents our Global scope so all the variables and functions that are defined globally we can access them via this window object so we can call window. console.log or simply just console. loock the JavaScript engine will prefix the statement with window. console dolog because that's where this object is defined similarly all these other functions you see here they belong to the window object so we can call window. set timeout or call it directly by the same token when we declare a variable let's say message that variable is also available via the window object okay however in the last section I told you that in node we we don't have this window object instead we have another object called Global so all these functions and objects we have here we can access them via the global object so we can do global. console.log or global. set time out and so on of course it's easier to use the shorthand instead of prefixing them with this Global but one thing you need to know about note is that these variables that we Define here they are not added to the global object in other words if we do a console.log of global. message we going to see undefined on the console so let me show you I'm going to delete all the code here now back in the terminal let's run node app.js so we get undefined in the console so as you can see the variables and functions that we Define here they are not add to the global object they're only scoped to this file app.js so they are not available outside of this file and this is because nodes modular system that you're going to learn about in the next lecture so in the last section you learn that in the client side JavaScript that we run inside of browsers when we declare a variable or a function that is added to the global scope for example when we Define a function like say hello that function is added to the global scope and it's available via the window object now there is a problem with this behavior in a real world application we often split our JavaScript code into multiple files so it is possible that we have two files and in both these files we Define this function say hello with the exact same name because this function is added to the global Scope when we Define this function in another file that new definition is going to overwrite the previous definition so this is the problem with the global scope so in order to build reliable and maintainable applications we should avoid defining variables and functions in the global scope instead we need modularity we need to create small building blocks or modules where we Define our variables and functions so two variables or two functions with the same name don't overwrite another variable or function defined somewhere else they're encapsulated inside of that module now at the core of node we have this concept called module so every file in a node application is considered a module the variables and functions we Define in that file or that module are scoped to that file in objectoriented programming terms we say they are private they are not available outside that container outside that module if you want to use a variable or a function defined in a module outside that module you need to explicitly export it and make it public and we're going to look at that in the next lecture so what I want you to take away from this lecture is that every node application has at least one file or one module which we call the main module so in this case this app.js is our main module now let me show you this module so I'm going to delete all the code here and do a console.log of module now this module object here may appear to be Global so you may think we can access it via the global object like global. console but actually this is not a global object it appears to be Global but it's not Global and you will find out why very soon so let's just log this module object and see what we see in the console back in the terminal node app.js so you can see we have an object module it's a Json object with these key value pairs so we have ID every module has an ID or a unique identifier we have exports parent file name which is the complete pass to that file loaded which is a Boolean that determines if this module is loaded or not we have children and Pats now for now don't worry about this proper ities as we go through this section you will gradually become familiar with this properties so in node every file is a module and the variables and functions defined in that file are scoped to that module they're not available outside of that module in the next lecture you're going to learn how to create and load a module all right now let's add a new module to this application so I'm going to add a new file logger JS let's imagine we're going to create a module for login messages and we're going to reuse this module in various parts of this application or potentially in other applications so logger JS now in this module let's imagine that we're going to use one of those remote logging services for login or messages so there are websites out there that provide logging as a service they give us a URL and we can send an HTTP request to that URL to log messages in the cloud so here I'm going to declare a variable like URL and set it to something like this http my logger.log and of course I'm making this up it may not be a true service out there but let's imagine in this implementation we're going to send an HTTP request to this endpoint to this URL now we also need a function called log that takes a message and in this function we're going to send an HTTP request however to keep things simple here we just want to focus on the modularity we don't want to get distracted with all the details of sending HTTP requests so for now I just want to log this message on the console so console.log message okay now this variable and this log function they're both scope to this module they're private they're not visible from the outside however in app.js which is our main module we want to use this logger module so we should be able to access this log function we should be able to call it from the app module so we need to make this public we need to make it visible from the out out side now in the last lecture you saw this module object one of the properties we have here is exports you can see this property is set to an empty object anything that we add to this object will be exported from this module and it will be available outside of this module so back in our logger module I'm going to set module do exports DOT log so I'm adding adding a method called log to this export object and simply setting it to this log function we have defined here okay in other words the object that we're exporting here has a single method called log now similarly if you want to export this URL we could do something like this so module. export. URL we set it to URL and of course we could change the name that is exported to the outside for example internally we may call this variable URL but when we export it we may call it endpoint okay now in this case we don't need to export this URL variable because this is purely implementation data so in real world applications every module might have several variables and functions we only want to export a substance of these members to the outside because we want to keep this module easy to use let me give you a metaphor think of a DVD player a DVD player has a few buttons on the outside and these are the buttons or objects that we interact with so these objects represent the public interface of a DVD player okay but inside the box there are lots of other objects or complex objects we don't need to know anything about these objects they're implementation detail and they can change significantly from one model to another but what we see on the outside is almost stable or static across different models so in our logger module this URL is implementation detail other modules don't need to know anything about this they only need to call the log function so we export this make it public but keep the URL private so I'm going to delete this last line okay so we are done with our logger module now we need to load this module and use it inside appjs to load the module we use the requir function this is one of the functions in node we don't have this in browsers this function takes one argument and that's the name or path of the target module we want to load so here we want to load the logger module now we can see both the app module and logger module are in the same folder so we use period slash to indicate the current folder and then we add the name of our module that is logger JS or we can make it shorter and just use logger because node assumes this is a Javascript file and it automatically adds the JS extension now if this logger was in a sub folder we could add that sub folder here or if it was in the parent folder we could use dot dot slash so here we're using the relative path to the Target module in this case that module is in the same folder now this required function Returns the object that is exported from this target module so this exports object here this is what we get when we call the required function let me show you so I'm going to declare a variable call it logger the name of the module and S it to the return value of the required function now let's log this logger and see what we get so node appjs look we get an object this object has a single method called log you can see that's a function so we can call this function or this method in appjs so back here we call logger Dot and look here we have intelligence in vs code so we call log and pass a message now back in terminal let's run this app and we get message on the console so this is how we work with modules in node when we Define a module we export one or more members and then to load them the module we use the required function now in the recent versions of JavaScript we have the ability to Define constants so as a best practice when loading a module using the required function it's better to store the result in a constant like this the reason for this is because we don't want to accidentally overwrite the value of loger like this here if we set this to one then when we call the log method we're going to get an exception let me show you so one more time look we got logger.log is not a function now in contrast if we Define this as a constant now back in the terminal let's run this program one more time look we got a different kind of error assignment to constant variable now there are tools out there that check our JavaScript code for errors like that so by using this constructs properly we can prevent these errors from happening at run time so one of these popular tools is JS hint if you have never used it before don't worry I'm just going to show you a quick demo so if you run JS hint app.js we get this error attempting to overwrite logger which is a constant so with tools like JS hint we can scan all our JavaScript code for errors like that so that's the benefit of using a constant as opposed to a variable here if we accidentally reset this object then we're going to get an error at compile time instead of at run time okay and one last thing before we finish this lecture sometimes instead of exporting an object from a module you may want to export only a single function for example here in our logger module we don't necessarily need an object because we have a single method an object would be useful if we had multiple methods or properties here but in this case instead of exporting an object we can export a single function so we can reset this export to the log function so initially it was an empty object but we reset it to just a function with that back in appjs So logger is no longer an object it's a function that we can call directly like this so logger we call it and give it an argument now a better name for this function is log so I'm going to press f2 to rename this log like this now back in terminal let's run node appjs and we get the same result so in your modules you can export a single function or an object so now you know the variables and functions with defined in a module are scoped to that module they're private and not visible from the outside but you might be wondering how node does this so let me show you on the very first line of the logger JS module I'm going to create a syntactical error so Define a variable X and set it to nothing like this so make sure to write this code on the very first line in other words if you have a line break here and do this on the second line you're not going to see what I'm going to show you now so put this back on the first line here we have a syntactical error now back in the terminal let's run the application again okay we got unexpected token semicolon right but look above this line you see this function declaration so this function has a few parameters exports require module file name and dur name so let me copy this code here now basically what happens under the hood is that node does not execute this code directly it wraps it inside of a function and that's the function you saw so at runtime our code is going to be converted to something like this so we have this function declaration here is the body of that function now for now I'm going to remove this error here so this is our code and then we have the end of this function now the actual code is slightly more complicated than this but we don't want to get distracted with that complexity if you're a more advanced JavaScript developer you probably know this is an immediately invoked function expression or ify if you don't know that don't worry that's not really the scope of node what I want you to take away here is that node does not execute our code directly it always wraps the code inside each module in something like this inside of a function now look at these arguments to this function so you have seen the required function I told you that this required function appears to be Global but actually it's not Global in fact it's local to each module so in every every module require is one of the arguments that is passed to this function we call this function the module wrapper function okay so you have seen the required function you have also seen module that is what we're using here so we have module. exports we also have exports which is a shortcut to module. exports so if you want to add a function to module. exports object you can either write module. exports log equals log or you can write exports. log equals log but you cannot reset this export like what we did earlier in other words you cannot write export equals log because this export is a reference to module that exports we cannot change that reference okay so the these are the first three arguments we also have file name and dur name which represent the name of this file and the path so let's have a quick look at these arguments on the top I'm going to do a console.log of underline underline file name and also underline underline durame now we're not going to have this function this module wrapper function this was purely for demonstration so I'm going to revert the code back to what we had before okay so now we don't have any errors in this module let's go back to the terminal and run this program so node appjs so here on the first line we have file name which is the complete pass to that file that is logger JS and on the second line we have the path to the directory that contains that module so now you have a basic idea about no modules and how they work you know how to create them how to load them but node itself comes with a bunch of useful modules that we can use in a lot of applications and that's what we're going to look at in the next lecture hi guys thank you for watching my node tutorial I wanted to let you know that this tutorial is the first hour of my complete node course where you will learn how to build a real restful API using node Express and mongod DB all of that recorded with the latest version of node and modern JavaScript so you will learn the new and modern ways of building applications with node unlike other courses that only show you simple dummy examples like how to build a to-do app we're going to work on a real world project a restful API for a video rental application if you have taken any of my courses you know I don't waste your time by explaining the obvious like what a code editor or command prompt is we're going to get straight to the business and as part of this I'll be touching on various important topics that you need to understand really well including working with node package manager or npm a synchronous JavaScript including callbacks promises Ayn and await implementing crud operations data validation authentication and authorization using Json web tokens including role management handling and login errors unit and and integration testing test driven development so you will see I will build a feature from A to Z using test driven development or tdd and finally we'll deploy this application to the cloud throughout the course I will share with you lots of clean coding and refactoring techniques security best practices useful libraries to use as part of your development common mistakes that many no developers make and much much more the course is currently 14 hours long and I'm planning to add more content to it in the future you can watch this course as many times as you want and if you watch it to the end you will get a certificate of completion that you can add to your resume so if you're serious about adding no to your resume I highly encourage you to enroll in the course and don't waste your time jumping from one tutorial to another so click on the link in the video description to enroll I hope to see you in the course so in the last lecture I told you that in node we have a few useful modules that are built into the core of node with these modules we can work with files with the operating system with the network and so on so let's have a quick look at this built-in modules head over to nodejs.org then go to docs on the left side go to version 8.9.2 that's the current stable release Chances Are by the time you're watching this video this version might be different so that doesn't really matter just pick that version now here in the table of contents you can see the built-in modules of course not everything you see here is a module for example we have console which is our console object we have buffer which we're going to learn about in the future in this course again that's global object but you can see that this is a fairly short list and some of the items in this list are built-in modules in note so just that you can see there are not many modules built into node I'm going to highlight a few very useful modules that you should be aware of for example we have file system to work with files we have HTTP that you're going to learn about later in this section so with this we can create web servers that listen for HTTP requests we have OS to work with the operating system we have path which gives us a bunch of utility functions for working with paths we we have process that gives us information about the current process we have query strings which is very useful in building HTTP Services we have a stream which allows us to work with streams of data again you're going to learn about this in the future and a bunch of other modules now in this lecture we're going to look at this path module so under the documentation we can see all the functions defined in this module in this lecture we're going to use the parse method now if you scroll down you can see how you can use this module so you have seen the required function before we call the module using the required function get the result which is an object and store it in a constant so back in vs code in appjs let's call require and as the argument use path now the argument that we give to this required function node assumes that this is a builting module if there is no buil-in module by the name specified here then node looks for the existence of a relative path to a file in this application so if we have period slash or period period slash whatever then node assumes that this is a file in this application now in this case we're going to load the buil-in pass module and store it in a constant called pass so this is an object with a bunch of useful methods the method we're going to use is the parse method so I'm going to give it this underline underline file name which is one of the arguments and the module wrapper function that you saw in the last lecture so let's call This And store the result in path object and then finally log it on the console pass object now back in the terminal Al let's run this application so this is the path object it has a few useful properties we have root we have dur which specifies the path to the folder containing this file here's the name of the file app.js here's the extension and here's the name of the file without the extension so if you want to work with path it's much easier to use the pass module as opposed to working with strings in the next lecture we're going to look at another built-in module that gives us information about the operating system in this lecture I'm going to show you how to get information about the current operating system so back in node documentation in the list of modules if you scroll down you can see this OS module let's have a quick look here so these are the methods that are available in this module for example we have free m which Returns the amount of free memory on this machine we also have total M which is the total memory we can get information about the current user we can get the up time of this machine and so on so let's use a couple of these methods here so if you scroll down you can see this is how we load this OS module just like loading other modules we call the required function and store the result in a constant called Os or anything so back back in vs code I'm going to delete all the code here and Define a new constant OS and set it to require OS now we can call Total me method or free or other methods so let me declare a variable and store the result here and similarly for the free memory free memory and finally let's log these values on the console so console.log single code we add total memory and append this total memory here now we can simplify this expression by using a template string which is available in more recent versions of JavaScript that we refer to as es6 or ES 2015 which is short for ecma script 6 or 2015 that's the specification that defines what features are available in JavaScript so every year egma defines new features that should be added to JavaScript and as you know different browsers Implement different set of these features but the V8 engine that we have inside of node that's pretty up to- dat and it implements a lot of new features of JavaScript that is defined in ecos script so in ecos script 6 or ecos script 2015 we have a feature called template string which helps us build a string without concatenations let me show you how that works so console.log now instead of a single code we use the backtick character backtick is the character before number one on your keyboard so here we add some static text like total memory now we want to add something here dynamically so we use dollar sign and curly braces to add a placeholder for an argument in this case our argument is this total memory variable so we can see with a template string we don't have concatenation okay now I'm going to duplicate this line and change total to free and here let's add free memory okay now we don't need this first console log we're done with this let's go back to the terminal and run this application so no app.js and you can see the total and free memory on my machine now what is interesting here is that before node we could not get this kind of information using JavaScript JavaScript used to run only inside of a browser and we could only work with the window or document OB objects we couldn't get information about the operating system but when using Noe our JavaScript code is executed outside of a browser or as some people say on the server with this we can get information about the operating system we can work with files we can work with the network for example we can build a web server that listens for HTTP requests on a given port and I'm going to show you all this later in this section in this lecture I'm going to show you how to work with files in node so back in node documentation and the list of modules here we have a module called file system in this module we have a comprehensive set of methods for working with files and directories now in this course I'm not going to waste your time showing you every single method here because that would be very repetitive but let me show you an example so you see how to work with file in node so back in vs code first we need to require the fs module we get the result and store it in this constant now FS dot look almost every operation defined here comes in two forms synchronous or blocking and asynchronous or non-blocking for example look we have access which is an asynchronous method we also have access Sy L which is a synchronous method now even though we have these synchronous methods here you should avoid using them these are there purely for Simplicity in a real word application you should use asynchronous methods because these are non-blocking so as I told you in the last section a node process has a single thread if you're using node to build the backend for your application you might have several hundreds or thousands of clients connecting to that backend if you keep that single thread busy you won't be able to serve many clients so always use a synchronous method now that aside let's take a look at an example we're going to look at read dir or directory method first I'm going to show you the synchronous form because that's easier to understand so as the first argument we specify the path period SL represents the current folder and this will return all the files and folders in the current folder so files will be a string array now we can display that on the console very simple so node app.js so you can see we get an array of strings and these are the files in this folder on my machine now let's take a look at the asynchronous form of this method so fs. read directory just like before the first argument is the path so the current folder now all these asynchronous methods take a function as their last argument node will call this function when that asynchronous operation completes we call this function a call back so here look in the intelligence the second parameter is a call back and this is a function with two parameters an error and result which is in this case a string array so here we need to pass a function or a callback function with an error and the result which is a string array we can call that files so here we need to check if we have an error or the result only one of these arguments will have a value and the other will be null so if we have error we're going to display it on the console error error now this is not how we handle errors in a rear World application but don't worry about this later in the course we have a complete section about error handling in Noe for now we just want to display this error on the console so if you have an error we displayed otherwise we display the result so console.log result and we can display this string array so I'm going to comment out these two lines so we can only look at the result of this a synchronous read directory now node appjs so we got result and this is exactly the string array that we had before now let's simulate an error so I'm going to go back in the code and change this argument to let's say a dollar sign save back at the terminal node appjs this time we got an error no such file or directory so to recap in order to work with files and directories in node first you need to require the fs module and then use one or more of the methods defined in this module all these methods come in pairs asynchronous and synchronous always prefer to use asynchronous methods one of the Core Concepts in node is the concept of events in fact a lot of nodes core functionality is based on this concept of events an event is basically a signal that indicates that something has happened in our application for example in node we have a class called HTTP that we can use to build a web server so we listen on a given port and every time we receive a request on that Port that HTTP class raises an event now our job is to respond to that event which basically involves reading that request and returning the right response so as you go through noes documentation you can see that several classes in node raises different kinds of events and in your code you might be interested to respond to those events so in this lecture I'm going to show you how to work with the events module now back in noes documentation once again in the list of modules you can see here we have this events module so in this module we have one class that is called event emiter it's one of the core building blocks of node and a lot of classes are based on this event emiter so let's see how we can work with this event emiter back in vs code first let's load the events module so require events now here when we call the required function we get the event emiter class so constant event emiter note that here in terms of the naming the first letter of every word is uppercase this is a convention that indicates that this event emiter is a class it's not a function it's not a simple value it's a Class A Class is container for properties and functions which we call methods so in this event emitor class we have these methods that you see here in the documentation so a class is a container for a bunch of related methods and properties now here in order to use this event emiter first we need to create an instance of this class so constant Emer we set this to new event emiter so here this emiter is an object in case you don't know the difference between a class and an object let me give you a metaphor a class is like human and an object is like an actual person like John Mary and so on so a class defines the properties and behavior of a concept like a human but an object is an actual instance of that class okay so here this first event emiter is a class it's a blueprint it defines what an event Emer can do but this second Emer is an actual object this is the one that we're going to use in our applic ation so this emiter has a bunch of methods look these are all the methods that you saw in the documentation now even though here we have more than 10 methods most of the time we use only two of these methods one is emate that we use to raise an event the first time I saw this method it didn't make sense to me because English is my second language and I didn't know what emit means so if you're in the same boat mate basically means making a noise or produce something in this case you're making a noise in our application we're signaling that an event has happened okay so that's the meaning of emit now here we pass an argument that is the name of the event let's say message logged in the future we're going to extend our logger module and every time we log a message we're going to raise an event called m message logged okay now if you run this application nothing is going to happen let me show you back in the terminal node appjs look nothing happened because we have raised an event here but nowhere in our application we have registered a listener that is interested in that event a listener is a function that will be called when that event is raised okay so let's register a listener that will be called when the message logged event is raised so register a listener so emiter dot look here we have this method at listener but we have an alias for this that we use more often that is on if you have worked with J Cy you have seen this before so on or at listener they're exactly the same but quite often we use the on method now this method takes two arguments the first one is the name of the event in this case message logged and the second one is a call back function or the actual listener so here we pass a function and this function will be called when that event is raised okay now for now I just want to log a message in the console so console let's say listener called like this now let's run this application so node appjs and we got this message listener called so this indicates that when we raise this event this callback function or listener was called okay and of course the order is important here if you registered this listener after calling the emit method nothing would have happened because when we call the emit method this emitor iterates over all the registered listeners and calls them synchronously okay so this is the basic of raising events and handling them using the Evan emiter class now quite often when we want to raise an event we also want to send some data about that event for example in our logger module when we log a message perhaps our remote login service will generate an ID for that message perhaps we want to reach return that ID to the client or it may give us a URL to access that logged message directly so here when raising an event we can add additional arguments which we refer to as event arguments so we can add an ID like one and we can add a URL but as you can see these magic values here are a little bit confusing if you want to send multiple values about an event it's a better practice to encapsulate those values inside an object so here we add an object we give it a couple of properties like ID we set it to ID of this message that is logged and another property URL like this okay so we're refer to this object as event argument now when registering a listener here this collect function this actual listener can also receive leave this event argument so here we add a parameter called Arc you can call it anything the name doesn't matter but by convention we often use ARG or some people use e to refer to the event or event Arc whatever you prefer is perfectly fine so here we have Arc now let's log it on the console very simple let's run this application so no mode okay look listener called and here's our event Arc and with this technique we can pass data about the event that just happened now one last thing to make this code a little bit simpler in es6 or ecos script 6 we have this feature called Arrow function with an arrow function we can get rid of this function keyword so here we have the arguments and after that we have the B body of that function now to separate the two we use an arrow and that's why we call this Arrow function you can see this syntax is a little bit simpler and a lot of people prefer to use Arrow functions in es6 now here's a simple exercise for you let's imagine in our logger module just before calling our remote service to log the message we're going to raise an event called logging and while raising this event we also want to send some data that is the message that we're going to log so what I want you to do is to use what you have learned in this lecture and raise and handle this logging event it's a very simple exercise I just want you to get used to this syntax now in the real world it's quite rare that you would work with this event emiter object directly instead you want to create a class that has all the capabilities of the event emiter and then you will use that class in your code let me explain what I mean by that and why so let's open up our logger module so in this module we're exporting a simple function log right and here we log that message on the console now after this we want to raise an event and then later in app module we will listen for that event and do something so let's go back to our app module and copy some code into the logger module so on the top I'm going to copy these two lines to bring the event emiter in this module okay and back in app module I'm also going to move these two lines for raising an event into the logger module because this code should not be here it's the logger module that emits or signals an event same the message is logged so cut so here after we log the message we raise an event like this okay now back in app module we don't need this comment here we need to load the logger module and call the log function so constant log we call the required function and set the path to the logger module and here we simply call the log function with a message okay now when we run this application we are only going to see this message on the console in other words this event listener will not be called let's verify that and then I will explain why that happens so back in terminal node appjs look we only got the message on the console so our event listener was not called the reason for this is because here we're working with two different event emitter in appjs we have this event emiter object and in logger module we have another event Emer object so earlier I told you that a class is like a blueprint and an object is an actual instance as a metaphor I said we could have a class called human or person but the objects could be Jack John Mary Bob whatever so in this case we have two different objects in the logger module you're using this Emer object to emit an event whereas in app module we're using another event Emer object to handle that event these are completely different so when we register a listener here that listener is only registered with this event emiter which is completely different from the other event Emer so that's why I told you in your applications it's very rare that you would want to work with this event emiter directly instead you want to create a class that has all the capabilities of this event emiter but it has additional capabilities in this case we want to create a class called logger that has this additional method log okay so the first thing you want to do here is to define a class in es6 we have this keyword class which is a syntactical sugar for creating a Constructor function with this we can define a class logger note that the first letter of every word in a class should be uppercase this is the Pascal case convention that we use for naming classes so class logger we have a code block now we need to move this log function inside this logger class so cut paste it here now we have an error because when we Define a function inside a class we don't need this function keyword and from now on we refer to this function as a method so when a function is inside a class we say that's a method in that class okay so here we have this logger class now at the end instead of exporting the log function we're going to export the logger class okay now we want this logger class to have all the capabilities of this event emiter the way we do that is by using the extends keyword that comes in es6 so extends and here we add the name of the parent or the base class so event emiter and with this simple change this logger class will have all the functionality that is defined in event emiter so here when raising this event instead of using this emiter object we're going to use this so in this class we can directly emit or raise events okay and now we no longer need this actual emiter object because we have not used it anywhere in this code so delete we're done with the logger module now back in the app module so here when requiring the logger module we get a class so I'm going to rename this to logger with capital L that's a class now we create an object so new logger and then to log a message we call logger.log now similar to the change that we made in the logger module we no longer need this event and object here we want to work directly with this logger object so we're going to register this listener on this logger object okay so I'm going to move this code after creating the logger we say hey logger when you raise this message logged event I want to execute this code okay and finally you can see we no longer need this event Emer object it's not used anywhere delete now when run this application we're going to see this message on the console but also because we're using the same logger object for registering an event listener and also raising an event we're going to see this message on the console so node appjs look this is the message on the console and you can see our listener was successfully called so let's quickly recap if you want to raise events in your application to signal that something has happened you need to create a class that extends event emiter with this that class will have all the functionality defined in event emiter but you can also add additional functionality in this case we have the ability to log a message and then inside that class whenever you want to raise an event you use this that iate because this references this logger class itself which extends event Emer so all the methods defined in event Emer will also be part of this class okay and finally in app module again instead of using an instance of event emiter you will use an instance of the custom class that you have defined that extends event Emer one of the powerful building blocks of node is the h HTP module that we use for creating networking applications for example we can create a web server that listens for HTTP requests on a given port and with this we can easily create a backend service for our client applications like a web application that we built with react or angular or a mobile application running on a mobile device so once again back in the node documentation in the list of modules you can find this HTTP module in this module you can see various classes like http.sys server this is one of the functions defined in this module and with this we can create a web server so let's store the result in a server object now what is interesting is that this server is an event emiter so it has all the capabilities of event emiter that you saw earlier in the section so look server dot we have the on method or ad listener or emit and so on also if you look at the documentation for the HTTP module on this page you can see httpserver class here the documentation says that this class inherits from net. server so this is another class defined in the net module let's have a look now here the documentation says that net do server is an event emiter so that's why I said a bunch of noes core functionality is based on event emiter so back to our server object now we can call server listen and give it a port let's say Port 3000 now following that I'm going to add a console.log saying listening on Port 3000 okay now when we run this application This Server will listen on Port 3000 as I told you before every time there is a new connection or new request This Server raises an event so we can use the on method to handle that event so before listening we want to register a listener or a Handler so server do on the name of the event is connection that you can find in the documentation so you don't have to memorize any of this stuff okay and the second argument is a callback function or the actual listener as you can see in the tool tip here this listener is a function with one argument that is Socket of type socket class and it returns void so here we have the arrow function syntax in es6 so let's add an arrow function that takes a socket and goes to this code block now here we can simply lck something on the console new connection now back in the terminal let's run this application you can see we're listening on Port 3000 now back in the browser let's head over to Local Host Port 3000 and now if you look in the terminal you can see we have a new connection here so you can see This Server object raises different kinds of events that you can respond to now in real world applications we are not going to respond to the connection event to build and HTTP service this is very low level so let's delete this what we commonly do is we pass a callback function to this create server method so function this function takes to parameters request and response or we can use the aror function syntax so we remove the function keyword and add this fat Arrow here now in this function instead of working with a socket we can work with the actual request or response objects so we can check if request. URL equals slash then we can send something to the client for example response. right hello world and then we end the response okay now back in the terminal we can exit here by pressing control and c and then run the application again okay we're still listening on Port 3000 let's refresh this page so we got hello world on the homepage now if you want to build a backend service for our web or mobile applications we need to handle various routes here for example we can have another if block if request. URL equals slash API SL courses perhaps here we want to return the list of courses from the database so we would do something like this response do right now here we want to return an array of objects using Json so we use Json Dot stringify and give it an array of objects now for Simplicity here we don't have to worry about the database or complex objects let's just return an array of numbers one two two and three so we pass this to json. stringify which will convert this array into a string using Json syntax and then we'll write it to the response and finally response. end now back in the terminal we need to stop this process again and run it one more time now in the future I will show you how we can automate this so every time we make a simple change to our application we don't have to restart it so now back in the browser if we go to slash API SLC courses we get an array with three numbers so as you see building a web server with node is very easy now in the real world we are not going to use this HTTP module to build a backend service for our application the reason for this is because as you can see here as we add more routes this code gets more complex because we add add all of them in a linear way inside this callback function so instead we use a framework called Express which gives our application a clean structure to handle various routes internally the Express framework is built on top of the HTTP module in node