Get started using Node.js to create backend applications
Get started using Node.js to create backend applications
"Node.js is an open-source, cross-platform, back-end, JavaScript runtime environment that executes JavaScript code outside a web browser." - Wikipedia
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
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.
Understand how Node.js applications are built
Implement a TODO application using Node.js
Implement REST APIs using Express.js
Get started using Node.js to create backend applications
"Node.js is an open-source, cross-platform, back-end, JavaScript runtime environment that executes JavaScript code outside a web browser." - Wikipedia
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
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.
Understand how Node.js applications are built
Implement a TODO application using Node.js
Implement REST APIs using Express.js
To open a new terminal, click on the menu > View > Terminal. The menu button is on the top-left (three horizontal bars).

~/workspace/bytes/ directory and cd to it
mkdir -p ~/workspace/bytes/
cd ~/workspace/bytes/
~/workspace/bytes/ directory using one of the following commands:
git clone https://gitlab.crio.do/crio_bytes/me_nodejs_basics.git
git clone git@gitlab.crio.do:crio_bytes/me_nodejs_basics.git
Now that you have fetched all the required source files, you can open them in the online IDE by following these steps:
Click on the Open Folder button.
Select the following folder /home/crio-user/workspace/bytes/me_nodejs_basics/ and Click on OK.

Please use the image above for illustration purposes only. The actual Byte name and the corresponding folder names will be different.
Execute the below command to install your project dependencies
npm install
Let’s look at how to create a simple server using Node.js
Open app.js file present in the root directory.
Copy the below lines of code to the app.js file
// 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}`)
});
node app.js in the terminal. You’ll see the below output
crio-user@nabhan-criodo:~/workspace/bytes/me_nodejs_basics$ node app.js
Nodejs server started on port 8081
curl command to send a GET request to localhost at port 8081. What does it print out?
curl -X GET http://localhost:8081
Visiting a URL from the browser sends a GET request
<workspace-ip>:8081 to view the server response
* If you are working locally, visit `localhost:8081` to view the server response
* If you are using GitPod can use the default options available in the terminal open Ports tab.

What is the difference in the response received using the  curl command and the browser?
Can you change the code in app.js to print out Created by <your-name-here> after the TODO heading?
You’ll have to restart the node server to reflect any change made after starting the server. To restart,
Enter Ctrl + c from the terminal where the server is running
Execute node app.js again
You can use the curl command’s -v flag to view the request and response headers as well
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
curl command prints out the response as such eg: curl -v http://localhost:8081
<h1>TODO<h1>

response.write() calls before response.end() is called to send more data or add in the same response.write() call itself. The two methods given below produce the same response body.
// Method 1
response.write('<h1>TODO</h1>');
response.write('<p>Created by: Crio.Do</p>');
// Method 2
response.write('<h1>TODO</h1><p>Created by: Crio.Do</p>');
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
What happens if you call the response.write() method after response.end() is called? (Hint: Check response body)
What happens if you call the response.write() method before the response.writeHead() method? (Hint: Check the response headers returned)?
What happens if you miss calling the response.end() method?
HTTP protocol supports multiple methods to perform different actions. Let’s look at some of these:
GET - used to retrieve some resource (eg: list of TODO items) from the server
POST - used to send some data to the server (eg: add new TODO item)
DELETE - used to delete a resource stored in the server (eg: delete a completed TODO item)
With your current server setup, to which of the above HTTP request methods does the server respond?
Try sending the request to different paths to the server eg: /, /random, /todo/1. Is there any difference in the responses?
Find out how to retrieve the request method and path (Ref)
Update the server callback function to return the data only if
The request path is /todos
The request is of type GET
When the request isn’t of type GET, return a 501 Not Implemented response status code
When the request path isn’t /todos, return a 404 Not Found response status code
Verify your implementation using the curl command
# GET request to path "/" - returns 404
curl -v -X GET http://localhost:8081/
# POST request to path "/todos" - returns 501
curl -v -X POST http://localhost:8081/
# GET request to path "/random" - returns 404
curl -v -X GET http://localhost:8081/random
# GET request to path "/todos" - returns 200
curl -v -X GET http://localhost:8081/todos 
If restarting the Node server for every change seems tedious, use the npm start command to start the application defined by the app.js file in monitoring mode. The application will automatically restart on any changes.
The server response is the same for any of the HTTP request methods as well as any path
You can fetch the details on the request method and path by using the request object’s method and url properties
const { method, url } = request;
Use an if clause to check if the path provided by 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
if (url == "/todos") {
    if (method == "GET") {
        response.writeHead(200, { 'Content-Type': 'text/html' });
        response.write('<h1>TODO</h1>');
        response.write('<p>Created by: Crio.Do</p>');
    } else {
        response.writeHead(501);
    }
} else {
    response.writeHead(404);
}
response.end();
You’ll get a similar response if you try to GET from http://localhost:8081/random. The response status code is 404 here.

Now that you have learned how to check for different routes and HTTP request types, go ahead and implement a backend Todo list application.
todoList and add a couple of TODO items to it, eg:
let todoList = ["Complete Node Byte", "Play Cricket"];
Update your callback function so that using the curl command to send
a GET request to the /todos path responds with the content of the todoList array
Implement a POST API for the path /todos
Request body will be JSON with a name property
Value of the name property gets added to todoList
Return a 201 Created status code
No response body is required
Example JSON data: { "name": “Plan for next week” }
Implement a DELETE API for the path /todos
Request body will be JSON with a name property
Value of the name property gets deleted from todoList, if present
Return a 204 No Content status code if a Todo item is deleted
No response body is required
Verify your implementation using curl commands
# GET request to path "/todos" returns contents of “todoList”
curl -X GET http://localhost:8081/todos
# POST request to path "/todos" adds a new TODO item
curl -X POST -d '{"name":"Plan for next week"}' http://localhost:8081/todos -H 'content-type:application/json'
# DELETE request to path "/todos" deletes a TODO item
curl -X DELETE -d '{"name":"Play Cricket"}' http://localhost:8081/todos -H 'content-type:application/json'
A 200 OK response status code is send by default if it’s not set explicitly
To complete the tasks, you’d have
if clause of the GET method condition to respond with the contents of the todoList array
if (method === "GET") {
    response.write(todoList.toString())
}
Added an else if clause to check for "POST" requests
The request object is a stream and it’s data and end events can be used to fetch the data
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
Push value of the name property of the request JSON data to todoList
else if (method === "POST") {
    let body = '';
    request.on('error', (err) => {
        console.error(err);
    }).on('data', (chunk) => {
        body += chunk;
    }).on('end', () => {
        body = JSON.parse(body);
        todoList.push(body.name)
    });
} 
DELETE request
else if (method === "DELETE") {
    let body = '';
    request.on('error', (err) => {
        console.error(err);
    }).on('data', (chunk) => {
        body += chunk;
    }).on('end', () => {
        body = JSON.parse(body);
        let deleteTodo = body.name;
        for (let i = 0; i < todoList.length; i++) {
            if (todoList[i] === deleteTodo) {
                todoList.splice(i, 1);
            }
        }
    });
} 
Here’s the complete content of the app.js file for your reference.
GET request to support URL parameters by which users can specify the number of TODO items in their list to view. Eg: /todos?n=5 should return the first 5 items in the TODO list (Ref)Express.js is a Node.js framework and makes it easier to build APIs.
You’ll implement the same GET, POST and DELETE APIs you created in the previous milestone using Express. You can then compare both the implementations to view how Express.js makes it easier.
Create a new file called app-http.js and move you current code from app.js to the new file
Import the express library using the require keyword
Start the app if it isn’t running. You’ll find that the app crashes due to an error
internal/modules/cjs/loader.js:896
  throw err;
  ^
Error: Cannot find module 'express'
http library exactly the same way earlier, right? Why didn’t it throw an error then?Once you add the import statement as given below to import Express to your project, the Node server will try to find the module. As express is not an built-in Node module whereas http was, you have to install express explicitly.
const express = require('express')
As a Google search puts it down,
"npm [or Node Package Manager] is a package manager for the JavaScript programming language"
For you, this just means that npm is like GitHub for JavaScript packages from where you can download it.
The package.json file is a special configuration file node uses to store metadata on it’s projects. You can add any number of project dependencies there and anyone who needs to setup your project can just execute npm install to get the project working on their system.
Let’s use npm to get express
Find the Express package in the npm registry (Yeah, Google Search!)
Add express dependency to your package.json file
Any patch or minor release of the version you see in the express page in npm registry should be acceptable
Install the dependencies and ensure the application starts without any errors
You’ll find the Express package in the npm registry here. A snapshot of the page is given below (Note: The version number can be different for you)

Dependencies in the package.json file goes inside the dependencies field. Instead of configuring our project to be dependent on some exact version of a library, we can use semantic versioning to be flexible.
The npm packages follows the convention where versions are named x.y.z
x is the major version i.e, involving new functionalities that are backward incompatible
y is the minor version i.e, involving new functionalities that are backward compatible
z is the patch version i.e, involving bug fixes that are backward compatible
The ^ option allows to use any minor or patch version of the specified version
"express": "^4.17.1"
Install the express library by executing npm install. This will pickup the dependencies specified in the package.json file. Starting the application again won’t show the error now.
What is happening when you execute npm start?
Check which libraries are there in your package.json file as dependencies. Now, try executing npm install cors to install a new library. Does this action modify your package.json library?
Routing is how the server responds differently to the client. The response to a GET request to the / path may not be the same as that of a POST request to the same path.
Implement the GET API to the /todos path using Express
The response should be the contents of the todoList array
Check the response using curl command
curl -X GET http://localhost:8081/todos
express() method
const app = express()
For each HTTP request method, Express has a separate method to set the callback function for that request. For GET, you use app.get()
The response object’s send() method is used to send the response body
app.get("/todos", (request,response) => {
    response.send(todoList);
});
listen() method on the Express application, app
const port = 8081;
app.listen(port, function(){
    console.log(`Nodejs server started on port ${port}`)
});
Now that you got a glimpse of how to create an API using Express, go ahead and implement the rest of the APIs
Use the built-in express.json() function to parse the request body as JSON
Implement a POST API for the path /todos
Request body will be JSON with a name property
Value of the name property gets added to todoList
Return a 201 Created status code
No response body is required
Implement a DELETE API for the path /todos
Request body will be JSON with a name property
Value of the name property gets deleted from todoList, if present
Return a 204 No Content status code if a Todo item is deleted
No response body is required
Any other request method to /todos  should return a 501 Not Implemented status code
Requests to any path other than /todos should return a 404 Not Found status code
# GET request to path "/todos" returns contents of “todoList”
curl -v -X GET http://localhost:8081/todos
# POST request to path "/todos" adds a new TODO item
curl -X POST -d '{"name":"Plan for next week"}' http://localhost:8081/todos -H 'content-type:application/json'
# DELETE request to path "/todos" deletes a TODO item
curl -v -X DELETE -d '{"name":"Play Cricket"}' http://localhost:3000/todos -H 'content-type:application/json'
Add express.json() to parse the request body as JSON.
app.use(express.json())
This is how you implement a POST request
app.post("/todos", (request, response) => {
    let newTodo = request.body.name;
    todoList.push(newTodo);
    response.status(201).end();
});
app.post() method is used to listen for a POST request
You can directly access the properties of the JSON request body using request.body.<property-name>.
You can use request.body.name here
This is easier in contrast to how you did it with the http module where you first read data into a stream, parsed it as JSON and then retrieved the property value
response.status() can be used to explicitly set a response status code in Express
By default, Express sets a
200 status code if a route matches
404 status code if no route matches
To set a different status code let’s say 400, use `response.status(400)
Even if you don’t have to return any data,
you’ll have to call response.send() method to let Node know the response is completed.
response.end() is another alternative here.
Similarly, you can implement the DELETE request and return a 204 status code
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();
        }
    }
});
Let’s also look at how to satisfy rest of the requirements
/todos other than GET, POST and DELETE, you can use the app.all() method below the current set of routes
app.all("/todos", (request, response) => {
    response.status(501).send()
})
To send a 404 status code to any other requests
Express returns a 404 status code with HTML content by default for any unimplemented route
You can also use the app.all() method at the end to add a custom 404 handler
app.all("*", (request, response) => {
    response.status(404);
    response.send("<Custom 404 message>");
})
Find the complete Express implementation here
/user/todos. You can catch me up there. Love, /todos”. How do you implement it? (Ref 1, 2, 3)Node.js is a backend JavaScript runtime environment to to execute JS code without a browser
You can use it to build to web server that listens for client requests and responds to it
Node’s built-in http module’s createServer() method can be used to create an HTTP server
The createServer() method accepts a callback function with two parameters, request and response
request denotes the incoming request object
response denotes the response object which will be send back to the client
The callback function gets executed every time a new request is received
The request object has properties like
method - type of HTTP request method
url - path of the resource requested for
headers - request headers
You can use these values to conditionally respond to the requests based on the request properties like HTTP method, path or headers
The response object methods can be used to set the response
To set a response status code and headers, use the writeHead() method exposed by the response object. Eg: response.writeHead(200, { 'Content-Type': 'text/html' });
write() method accepts the text to be sent as response body
end() method tells the server the request has been completed
To bind the HTTP server created using createServer() to a specific port, use the listen() method
To read data sent as request body, use the request object’s data and end events
data event is triggered if there’s data remaining in the stream to be read
end event is triggered if the request data stream is empty
NPM is a repository for JavaScript packages.
You can use npm install to download your project dependencies from the NPM registry
The package.json file can be used to specify your project dependencies using its dependencies field
Express.js is a Node framework for creating web applications and APIs
You create an Express application handler by const express = require(‘express’); const app = express()
It provides methods for each of the HTTP request method types like
app.get() for GET request
app.post() for POST request
app.all() is a special method that listens to all HTTP request types to a particular path
To specify the callback for a particular route, let’s say GET request to /user, you do app.get("/user", callbackFunction)
Using Express’s inbuilt json middleware, we can directly parse the JSON request body as a JavaScript object.
To do that, add app.use(express.json()) before any routes
You can use for example, request.body.jsonProperty1 to fetch a property in your request body, "jsonProperty1"
The response object’s methods to use are
status() - to set the response status code
send() - send response body data
end() - trigger end of response
Find the
Further Reading
Knowledge of the Node.js backend framework
Know-how of the Express.js library
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