'N' and 'E' of MERN - Basics of Node.js and Express.js
Tags: javascript, webdev, tutorial, beginners
Published: 2021-07-21 13:06:04

##Introduction
###What is Node.js?
```Node.js is an open-source, cross-platform, back-end, JavaScript runtime environment that executes JavaScript code outside a web browser.```
**Open source** - because it’s source code is available for use and modification legally.
**Cross platform** - works across different platforms like Linux, OSX and Windows.
**Backend** - receives requests from clients and contains the logic to respond to it.
**JS runtime environment** - where JavaScript code gets parsed and executed.

Node is a JavaScript environment built on the same JavaScript engine used in Google’s Chrome web browser. It has some great features that make it an attractive choice for building server-side applications, including web servers and web services for platform APIs.

Primary goals of this article -
* _Understand how Node.js applications are built_
* _Implement a TODO application using Node.js_
* _Implement REST APIs using Express.js_

**Prerequisite** - As Node.js is based on JavaScript, it’s easier to learn to get started with for developers who know JavaScript. This also means that both the frontend and backend can now be written with just JavaScript knowledge.

Before we jump in, make sure you have node installed.
Install from [Here](https://nodejs.org/en/).

Let's get started-
Let’s look at how to create a simple server using Node.js

create a file app.js and paste the following code-
```javascript
// File: app.js

const http = require('http');
const port = 8081;

http.createServer((request, response) => {

    // Set response status code and response headers
    response.writeHead(200, { 'Content-Type': 'text/html' });

    // Set response body i.e, data to be sent
    response.write('<h1>TODO</h1>');

    // Tell the server the response is complete and to close the connection
    response.end();

}).listen(port, () => {

    // Log text to the terminal once the server starts
    console.log(`Nodejs server started on port ${port}`)

});
```
Execute `node app.js` in the terminal. You will see the following in terminal-
```
Nodejs server started on port 8081
```
Basically your server has started on port 8081 !!
Let's test it with `curl`:
```curl -X GET http://localhost:8081```
Or visit `http://localhost:8081` in your browser to see the response sent by the above server.
That’s it! You’ve just built your first Node app.

So, What's happening with above code?
`http` is an inbuilt Node module, you can use `require()` to import it.
The http module exposes a function `createServer()` which can be used to create an HTTP server.
You have to pass a callback function as a parameter to the createServer() function. This function gets executed every time the server receives a request. The parameters to the callback function are the HTTP `request` and `response` objects.
We used these `response` object methods -
* writeHead() - the first parameter is the response status code and the second any response headers.
* write() - to add response body to be sent back to the client.
* end() - tells the server that the response is complete.
and OfCourse, we can add any number of `response.write()` calls before `response.end()` is called to send more data.

Here, We are just sending a h1 tag with text as 'TODO'.
curl command prints out the response as such-
```
<h1>TODO<h1>
```
The browser renders the HTML tag and displays an h1 heading with text, TODO.
![TODO browser render](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/94lb8lkadbr8u7kgmuk6.png)
* The listen() method sets the port in which the server listens to the requests.
You can also add a callback function to listen() which will get executed once, when the server starts. Normally, we add lines such as `Nodejs server started on port 8081` to make sure that server is listening.

##Routing
Ok. So currently our server sends same response (h1 Tag) with status code 200 to every( irrespective of url and method) request it receives.
Let's change the body of createServer() method with following-
```javascript
const { method, url } = request;
//fetch request method and path by using the request object’s method and url properties.

if (url == "/todos") {

    if (method == "GET") {
        response.writeHead(200, { 'Content-Type': 'text/html' });
        response.write('<h1>TODO</h1>');
        response.write('<p>Track your work</p>');
    } else {
        response.writeHead(501); //or response.statusCode = 501
    }

} else {
    response.writeHead(404);
}

response.end();
```

Now the server checks if url variable is /todos ?
If so, check if method is GET ?
If so, return the header and HTML response
Else, return just a 501 status code
Else, return 404 status code.

Now if you try to 
```curl -X GET http://localhost:8081/random```
Can you guess what response are you going to get from server?
The url path is /random, so server sends response with status code as 404.
if you try to 
```curl -X POST http://localhost:8081/todos```
yes, the url is /todos, but the method is POST, now you will get response code as 501.

_Note that - 200 OK response status code is send by default if it’s not set explicitly._

##Request Body
The `request` object that's passed in to a handler implements the `ReadableStream` interface. This stream can be listened to or piped elsewhere just like any other stream. We can grab the data right out of the stream by listening to the stream's 'data' and 'end' events.
The `request.on()` method can be used to look for the stream events. The data is read in chunks and is a buffer.
Once the whole data is read (known by the end event), you can parse the JSON data as a JavaScript object using the JSON.parse() function.
```javascript
let body = '';

    request.on('error', (err) => {
        console.error(err);

    }).on('data', (chunk) => {

        body += chunk;  //keep concatenating the chunk 

    }).on('end', () => {
        body = JSON.parse(body);
    });
```

##URL Module
What if we want to filter the response based on url parmaters??
We can use the Built-in `URL` Module-
The URL module splits up a web address into readable parts.
```javascript

var url = require('url');
var adr = 'http://localhost:8081/default.htm?year=2017&month=february';  //request.url
var q = url.parse(adr, true);

console.log(q.host); //returns 'localhost:8081'
console.log(q.pathname); //returns '/default.htm'
console.log(q.search); //returns '?year=2017&month=february'

var qdata = q.query; //returns an object: { year: 2017, month: 'february' }
console.log(qdata.month); //returns 'february'
```
_Now, If you have gone through the complete article up to this point, you have really good knowledge of Node.js and of course, there are always so many new things to explore._

#Express
Express.js is a Node.js framework and makes it easier to build APIs.
We will be implementing the same APIs we created using Node.js. You can then compare both the implementations to view how Express.js makes it easier.
First, let’s get Express to work on your system.
```
$ npm install express
```

Express enables you to create a web server that is more readable, flexible, and maintainable as compared to developing a web server using only the Node `HTTP` library, which can get complicated for even the most basic web servers.

###Routing in Express and HTTP Methods
The syntax for defining a route handler function is:
```app.httpMethod(path, handler) {...}```
Here, httpMethod can be get, put, post, delete, etc. The path is the actual route where the request will go and the handler is the same callback function which were passing to createServer() in node.js that is it will execute when the requested route is found.
Let's implement the `GET API` to the `/todos` path using `Express`

```javascript
const app = express();

app.get("/todos", (request,response) => {
    response.status(200);
    response.send('<h1>TODO</h1>');

});
const port = 8081;

app.listen(port, function(){

    console.log(`Nodejs server started on port ${port}`)

});
```
* Express Server is initialized using the express() method.
* For GET, we used app.get() method, likewise you will use app.post(), app.delete() etc. for other HTTP methods.
* The response object’s send() method is used to send the response body.
* To bind the server to a port, you use the listen() method on the Express application, app.

_As Javascript is a case-sensitive language, app.GET() won’t work._

##Express Middlewares
Middleware functions are those that have access to request and response objects just like we do within routes. Middlewares are capable of changing requests, response objects, and can end the response cycle as well. You can think of middleware as a stack of functions that gets executes whenever a request is made to the server.
Generally, a middleware function takes 3 parameters: a request object, a response object, and a "next" function. Whenever you write a middleware, you must call this next() function at the end of every middleware function you write. In order to use middleware in your application, you have to make a call to app.use() and pass a middleware function as an argument.
For example-
```javascript
// User defined Middleware
app.use(function(req, res, next){
   console.log('Inside Middleware function...');
   next();
});
```
If you do not call next(), no more route handlers or middleware will be processed. If still for some reason, you don't want to call next() then just send a response to the client, or else the client will remain in hang state and eventually get timed out.

Now we have basic understanding of Express, let's complete our TODO application using Express.

```javascript
const express = require('express'); 
//importing express

const app = express();
//initializing express app

app.use(express.json())
//express.json() middleware to parse the request body as JSON.

const port = 8081

let todoList = ["Complete writing blog", "Complete project"];

/* Get all TODOS:   
** curl -v http://localhost:8081/todos
*/
app.get("/todos", (request, response) => {
    response.send(todoList);
});

/* Add a TODO to the list
** curl -v -X POST -d '{"name":"Plan for next week"}' http://localhost:8081/todos -H 'content-type:application/json'
*/
app.post("/todos", (request, response) => {
    let newTodo = request.body.name;
    todoList.push(newTodo);
    response.status(201).send();
});

/* Delete a TODO to the list
** curl -v -X DELETE -d '{"name":"Complete writing blog"}' http://localhost:8081/todos
*/
app.delete("/todos", (request, response) => {
    let deleteTodo = request.body.name;
    console.log(deleteTodo);
    for (let i = 0; i < todoList.length; i++) {
        if (todoList[i] === deleteTodo) {
            todoList.splice(i, 1);
            response.status(204).send();
        }
    }
});

app.all("/todos", (request, response) => {
    response.status(501).send()
})

app.all("*", (request, response) => {
    response.status(404).send()
})

app.listen(port, () => {
    console.log(`Nodejs server started on port ${port}`)
});
```
What is app.all()?
To send a 501 status code for requests to `/todos` other than GET, POST and DELETE, we can use the app.all() method *below* the current set of routes.
_Express returns a 404 status code with HTML content by default for any unimplemented route or we can also use the app.all() method at the end to add a custom 404 handler._

##Conclusion
Congratulations on making till the end. We have learned a lot in this article, I hope you now have a decent knowledge of Node and Express. Now you can create simple applications using the Node.js framework, Use Node.js to create a web server that listens to multiple routes, Utilize the Express.js library in your Node applications. I will come with more articles on this topic soon.

Till then: Keep Learning :)

Also, please ❤️, if you liked this article.