Welcome to the future. Life is good, but it can be better. And why shouldn’t it be? All you need is to want it. Think about finally having everything you always wanted.
— Max Lord (Wonder Woman 1984)
I won’t say that I thought of Node.js when I first hear Max Lord saying those words in the trailer of upcoming wonder woman movie. However, it is close when we talk about building applications using Node.js. From working with devices to building web applications, sometimes that’s all you need.
In one of my previous posts, I wrote a brief introduction about Node.js. Node can be used in many places and today I will write about how Node can be used in web development. My idea is to keep these articles simple and same time build a path for more complex upcoming posts. If you are new to Node, I will suggest to first check my previous article here on DZone on this link, which will provide you the background context and will make it easy for you the follow the topics we are going to cover. So let’s start.
Built-in HTTP Module
Node has a built-in web-server and the code above is demonstrating a very basic web server. Actually, I took this screenshot from my last article, and here we are going to understand a little bit more in detail.
- The require call here returns something. It’s just a function call. This call returns the API of the module that we are requiring.
- We are capturing the API of the http module into a local variable, also named http. We could have named it something else, but its a convention usually.
- This local http variable now has all the methods defined on the public API of the http. module.
createServer is a higher-order function coz it receives another function as parameter.
We could have write the code as following as well:
requestListener function receives two arguments. These are positional arguments:
req = Represent the request side of the request-event.
res = Represents the response side of the request-event.
So, the requestListener here is a function that will be invoked every time there is a request event.
Server as Event-Emitter
The server object that we get as a result of calling the createServer() method is an event-emitter and one of the events it emits is named “request”.
In fact, this same code can be re-written using the event-emitter API:
Every time we have a request event coming to this sever, we are instructing the server object to execute our requestListener function.
Are you connecting the dots now?
Regardless of which route you take for creating the server, the RequestListener gets invoked.
- Inside the function we can read information about request using the reqobject. For example, we can read:
- What URL the user is requesting.
- What parameters they are sending along.
- What IP they are coming from and many other things.
- We can write data back to the requester using the res object which we are doing using .end() method (shorthand for .write and .end methods).
- Since this is an HTTP communication, we need to follow the HTTP protocol. The protocol for example, requires an explicit signal that the communication is over. This is exactly why we need to use the .end() method. This method is not optional because without that, the http session will think that we’re still streaming data to it.
CreateServer method only creates the server, it does not make it actively listening to requests. To run the server and activate it, we needed to call the .listen method on the server object.
The first argument is port and second is a callback function that will get invoked if the server reserved the port and started listening on it successfully.
Note also when we run this server, the Node process did not exit because the event-loop is now also busy listening the incoming connections on port and it will do that forever. More about event-loop in future post.
So, our running server has an active task and it is listening for incoming requests. However, this node process only uses V8 when there are HTTP connections, otherwise, V8 will remain idle. This listen function is actually the task that keeps node running busy and not exit.
Node Web Frameworks
- Although Node comes with built-in modules to work with HTTP (which we saw above), those modules are low-level and they offer limited capabilities.
- There are some frameworks available that wrap the built-in power in Node and expose a simpler API to create features in your web server. One of the popular ones is express.
- The other popular frameworks are:
- Meteor.js and many more
You can use npm to install express as follows. I also installed chalk (for console messages) as well.
- >> npm install express
- >> npm install chalk
Basic Express Server
This code is all we need to spin up a very simple express server.
Now, here is a difference in regard to built-in http server. We do not define a single request listener. We define many listeners. We actually define a listener per URL (url, http operations)
Let’s build a simple API using Node.js, express, and lodash. For persisting, I will use in-memory array, but feel free to use any persistence mechanism you like. One option could be JSON file using lowdb. For details about that part check my other article on DZone.
Here is what we will be building :
- API will allow users to perform CRUD operations.
- I will work with an array of Device object.
- We will see a nice pattern to encapsulate REST calls for specific entity (controller style).
Also all the source code is available via git and you can download it from the link in the summary section. The following screenshots will give you an overview of the building blocks. The code is self-explanatory but if something is not clear, feel free to ask in the comments.
Following is the server.js file which is our entire web-server code. This file reference (require) another module devices.js, which contains all the routes and actions. You can use Postman tool to make REST calls to test the API.
devices.js (CRUD Operations)
Read (GetAll) devices data:
You can test Update (PUT) and Delete operations in similar way.
You can download the code repo from this link. I will keep sharing my dev experiences with you. Till next time, happy coding.