Node Js
Node Js
Concepts in Focus
• MERN Stack
• Node JS
• Running JavaScript Using Node JS
• Node REPL (Read-Eval-Print-Loop)
• Node CLI
• Module
• Common JS Module Exports
• Modern JS Module Exports
1. MERN Stack
MERN stands for MongoDB, Express JS, React JS and Node JS.
It is a JavaScript Stack that is used for easier & faster deployment of full-stack web
applications.
2. Node JS
Node JS is a JavaScript environment that executes JavaScript code outside a web
browser.
Why Node JS?
• Cross-Platform (Windows, Linux, Mac OS X, etc.)
• Huge number of third-party packages
• Open Source
• Massive Community
root@123# node
Welcome to Node.js v12.18.3.
Type ".help" for more information.
> const a = 1
undefined
> const b = 2
undefined
> a+b
3
>
Type .exit and press Enter to exit from the Node REPL.
root@123# node
Welcome to Node.js v12.18.3.
Type ".help" for more information.
> const a = 1
undefined
> const b = 2
undefined
> a+b
3
> .exit
root@123:/home/workspace#
We can write JavaScript to a file and can run using Node CLI.
//index.js
greetings("Raju");
greetings("Abhi");
Output:
Note:
Save the file whenever the code changes.
4. Module:
In Node JS, each JavaScript file is treated as a separate module. These are known as
the Common JS/Node JS Modules.
To access one module from another module, we have Module Exports.
• Common JS Module Exports
• Default Exports
• Named Exports
• Modern JS Module Exports
• Default Exports
• Named Exports
Exporting Module
The
module.exports
is a special object included in every JavaScript file in the Node JS application by
default.
//calculator.js
Importing Module:
To import a module which is the local file, use the require() function with the
relative path of the module (file name).
//index.js
const add = require("./calculator");
console.log(add(6, 3));
OutPut:
1.root@123# node index.js
2. 9
Exporting Module
//calculator.js
const add = (a, b) => {
return a + b;
};
const sub = (a, b) => {
return a - b;
};
exports.add = add;
exports.sub = sub;
Importing Module:
//index.js
const { add, sub } = require("./calculator");
console.log(add(6, 3));
console.log(sub(6, 3));
Output:
root@123# node index.js
9
3
Exporting Module
//calculator.mjs
const add = (a, b) => {
return a + b;
};
export default add;
Importing Module:
//index.mjs
OutPut:
//calculator.mjs
Importing Module:
//index.mjs
Output:
Note:
We need to specify .mjs extension while importing ES6 Modules.
We may or may not need to specify .js while importing Common JS Modules.
Concepts in Focus
• Default Exports
• Exporting a variable while defining
• Exporting a variable after defining
• Exporting a value or an expression
• Exporting a function while defining
• Exporting a function after defining
• Exporting a class while defining
• Exporting a class after defining
• Named Exports
• Exporting multiple variables while defining
• Exporting multiple variables after defining
• Exporting multiple values and expressions
• Exporting multiple functions while defining
• Exporting multiple functions after defining
• Exporting multiple classes while defining
• Exporting multiple classes after defining
Let's see different scenarios that we may come across while exporting.
1. Default Exports
With Default Exports, we can import modules with any name.
1.1 Exporting a variable while defining
We cannot export boolean, number, string, null, undefined, objects, and arrays while
defining.
Example:
//sample.js
module.exports = let value = 5;
//index.js
const num = require("./sample.js");
Output:
root@123# node index.js
/index.js:3
module.exports = let value = 5;
^
SyntaxError: Unexpected identifier
at wrapSafe (internal/modules/cjs/loader.js:1053:16)
...
We can export boolean, number, string, null, undefined, objects, and arrays after
defining.
Example:
//sample.js
let value = 5;
module.exports = value;
//index.js
console.log(value);
Output:
root@123# node index.js
5
1.3 Exporting a value or an expression
We can export a value or an expression directly.
Example:
//sample.js
module.exports = 5 * 3;
//index.js
console.log(result);
Output:
//sample.js
//index.js
console.log(sum(2, 6));
Output:
console.log(sum(2, 6));
Output:
//index.js
console.log(studentDetails);
console.log(studentDetails.name);
Output:
class StudentDetails {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
module.exports = StudentDetails;
//index.js
console.log(studentDetails);
console.log(studentDetails.name);
Output:
2. Named Exports
//index.js
console.log(value);
console.log(studentName);
Output:
console.log(value);
console.log(studentName);
Output:
root@123# node index.js
5
Rahul
console.log(sum(2, 6));
console.log(sub(8, 3));
Output:
//index.js
Output:
class StudentDetails {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
exports.studentDetails = StudentDetails;
class CarDetails {
constructor(name, age) {
this.name = name;
this.speed = age;
}
}
exports.carDetails = CarDetails;
//index.js
Output:
Let's see different scenarios that we may come across while exporting.
1. Default Exports
With Default Exports, we can import modules with any name.
//sample.mjs
//index.mjs
Output:
root@123# node index.mjs
(node:31964) ExperimentalWarning: The ESM module loader is experimental.
file:///index.mjs:1
export default let value = 5;
^^^
SyntaxError: Unexpected strict mode reserved word
let a = 5;
export default a;
//index.mjs
Output:
root@123# node index.mjs
(node:32665) ExperimentalWarning: The ESM module loader is experimental.
5
export default 5 * 3;
//index.mjs
console.log(result);
Output:
//index.mjs
console.log(sum(2, 6));
Output:
//index.mjs
Output:
Output:
class StudentDetails {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
export default StudentDetails;
//index.mjs
Output:
root@123# node index.mjs
(node:1575) ExperimentalWarning: The ESM module loader is experimental.
StudentDetails {name: "Ram", age: 15}
Ram
2. Named Exports
2.1 Exporting multiple variables while defining
We can export boolean, number, string, null, undefined, objects, and arrays while
defining.
Example:
//sample.mjs
//index.mjs
console.log(studentName);
Output:
let value = 5;
const studentName = "Rahul";
//index.mjs
console.log(value);
console.log(studentName);
Output:
//index.mjs
console.log(sum(4, 2));
console.log(sub(4, 2));
Output:
//index.mjs
console.log(sub(4, 2));
Output:
//index.mjs
Output:
class StudentDetails {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
class CarDetails {
constructor(name, speed) {
this.name = name;
this.speed = speed;
}
}
//index.mjs
Output:
1. Core Modules
The Core Modules are inbuilt in Node JS.
Some of the most commonly used are:
Module Description
path Handles file paths
fs Handles the file system
url Parses the URL strings
1.1 Path
The path module provides utilities for working with file and directory paths. It can be
accessed using:
Example:
//index.js
console.log(filePath);
Output:
Note:
Many developers prefer Common JS Modules to ES6 syntax as ES6 syntax is in the
experimental phase.
2. Package
A package is a directory with one or more modules grouped.
2.1.1 CLI
NPM CLI sets up the Node JS Project to organize various modules and work with
third-party packages.
Command Description
npm init -y Initializes a project and creates a
Command Description
package.json file
npm install <package-name>
Installs the third-party packages
--save
4. Third-Party Packages
The Third-Party Packages are the external Node JS Packages.
They are developed by Node JS developers and are made available through the Node
ecosystem.
4.1 date-fns
It is a third-party package for manipulating JavaScript dates in a browser & Node.js.
Installation Command:
4.1.1 addDays
It adds the specified number of days to the given date.
Example:
//index.js
console.log(result);
Output:
Note:
While creating the Date() object, we have to provide the month index from (0-11),
whereas we will get the output considering Jan=1 and Dec=12.
Concepts in Focus:
• HTTP Server
• Server-side Web Frameworks
• Express JS
• Network Call using Express JS
• Handling HTTP Request
• Testing Network calls
• Network Call to get a Today’s Date
• Network Call to get HTML content as an HTTP Response
• Sending file as an HTTP Response
1. HTTP Server
• Works with the HTTP requests and responses
• Handles the different paths
• Handles the query parameters
• Sends the content as HTML, CSS, etc. as an HTTP response
• Works with the databases
2. Express JS
It is a free and open-source Server-side Web Application Framework for Node JS.
It provides a robust set of features to build web and mobile applications quickly and
easily.
Installation Command:
npm install express –save
Note:
Whenever the code changes, we need to restart the server to reflect the changes we
made.
An API is a software intermediary that allows two applications to talk to each other.
For example, OLA, and UBER use Google Maps API to provide their services.
All the Network calls that we added are also the APIs.
2. Database
Express apps can use any database supported by Node JS.
There are many popular options, including SQLite, PostgreSQL, MySQL, Redis, and
MongoDB.
3. SQLite
The SQLite provides a command-line tool sqlite3.
It allows the user to enter and execute SQL statements against an SQLite database.
4. SQLite Methods
4.1 Open
The SQLite
open()
method is used to connect the database server and provides a connection object to
operate on the database.
Syntax:
open({
filename: DATABASE_PATH,
driver: SQLITE_DATABASE_DRIVER,
});
It returns a promise object. On resolving the promise object, we will get the database
connection object.
4.2 Executing SQL Queries
SQLite package provides multiple methods to execute SQL queries on a database.
Some of them are:
• all()
• get()
• run()
• exec(), etc.
4.2.1 all()
db.all(SQL_QUERY);
The
all()
method is used to get multiple rows of data.
6. Connecting SQLite Database from Node JS to get the books from Goodreads
Website
1. Install the SQL third-party packages sqlite and sqlite3
.
2. Initialize the SQLite Database
Concepts in Focus
• SQLite Methods
• get()
• run()
• Node JS Third-party packages
• Nodemon
• GoodReads API
• Get Book
• Add Book
• Update Book
• Delete Book
• Get Author Books
1. SQLite Methods
The SQLite package provides multiple methods to execute SQL queries on a
database.
Some of them are:
• all()
• get()
• run()
• exec(), etc.
1.1 get()
The
get()
method is used to get a single row from the table.
Syntax:
db.get(SQL_QUERY);
1.2 run()
The
run()
method is used to create or update table data.
Syntax:
db.run(SQL_QUERY);
2.1 Nodemon
The Nodemon is a tool that restarts the server automatically whenever we make
changes in the file.
Installation Command:
npm install -g nodemon
Note:
The -g indicates that the nodemon will be installed globally in the environment.
While executing the file, replace the node with the nodemon. For example, nodemon
index.js.
3. GoodReads APIs
• Get Book
• Add Book
• Update Book
• Delete Book
• Get Author Books
The
dbResponse.lastID
provides the primary key of the new row inserted.
Note: The strings sent through the APIs must be wrapped in quotes.
3.4 Delete Book
REST APIs
Concepts in Focus
• Get Books API
• Filtering Books
• REST APIs
• Why Rest Principles?
• REST API Principles
http://localhost:3000/books/?offset=2&limit=3
http://localhost:3000/authors/20/books/?offset=2
Note :
Note:
We can skip or add slash while appending query parameters to the URL
http://localhost:3000/books/?offset=2&limit=3
is same as
http://localhost:3000/books?offset=2&limit=3
2. REST APIs
REST: Representational State Transfer
REST is a set of principles that define how Web standards, such as HTTP and URLs,
are supposed to be used.
Concepts in Focus
• Importing Unknown Modules
• Starting Server in Multiple Terminals
• Starting Server outside the myapp
• Accessing Wrong URL
• Missing Function Call
• Importing Unknown File
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /bookss/1/</pre>
</body>
</html
5. Missing Function Call
When we miss calling the function express and trying to access methods returned
from the function express
root@123:/.../...part-3/myapp# nodemon index.js
[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node index.js`
/home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/myapp/
index.js:26
app.get("/books/", async (request, response) => {
^
Concepts in Focus
• Request Methods
• Missing colon(:)
• Accessing Path Parameters
• Query Formatting
• Replacing SQLite Methods
• HTTP Request URL
• Missing '?'
• Missing ‘&’ between Query Parameters
• Replacing '&' with ',' in Query Parameters
• Accessing Unknown Database
• Accessing Wrong Port Number
1. Request Methods
When we try to request with a wrong method
HTTP/1.1 404 Not Found
X-Powered-By: Express
Content-Security-Policy: default-src 'none'
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 148
Date: Sun, 04 Apr 2021 11:50:56 GMT
Connection: close
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /books/</pre>
</body>
</html
2. Missing colon(:)
4. Query Formatting
When we miss embedding expression into string literal properly in the query
root@123:/.../...part-3/myapp# nodemon index.js
[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node index.js`
Server Running at http://localhost:3000/
(node:1023) UnhandledPromiseRejectionWarning: Error: SQLITE_ERROR: no such
table: book
(node:1023) UnhandledPromiseRejectionWarning: Unhandled promise rejection.
This error originated either by throwing inside of an async function without a catch
block, or by rejecting a promise which was not handled with .catch(). To terminate
the node process on unhandled promise rejection, use the CLI flag `--unhandled-
rejections=strict` (see
https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:1023) [DEP0018] DeprecationWarning: Unhandled promise rejections are
deprecated. In the future, promise rejections that are not handled will terminate the
Node.js process with a non-zero exit code.
{
"stmt":{},
"lastID":0,
"changes":0
}
6.1 Missing ?
When we miss ? before starting query parameters
HTTP/1.1 404 Not Found
X-Powered-By: Express
Content-Security-Policy: default-src 'none'
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 148
Date: Sun, 04 Apr 2021 11:50:56 GMT
Connection: close
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET
http://localhost:3000/books/offset=2&limit=3&search_q=potter&order_by=price&or
der=DESC</pre>
</body>
</html>
6.2 Missing & between Query Parameters
When we are trying to access the wrong port number, we may get the below
notification
The connection was rejected. Either the requested service isn’t running on the
requested server/port, the proxy settings in vscode are misconfigured, or a firewall is
blocking requests. Details: RequestError: connect ECONNREFUSED
127.0.0.1:4000.
Authentication:
Concepts in Focus
Authentication Part 2:
Authentication Mechanisms
• Token Authentication mechanism
• Access Token
• How Token Authentication works?
• JWT
• How JWT works?
• JWT Package
• Login User API by generating the JWT Token
• How to pass JWT Token?
• Get Books API with Token Authentication
1. Authentication Mechanisms
To check whether the user is logged in or not we use different Authentication
mechanisms
Commonly used Authentication mechanisms:
• Token Authentication
• Session Authentication
3. JWT
JSON Web Token is a standard used to create access tokens for an application This
access token can also be called as JWT Token
When the user tries to log in, verify the Password. Returns JWT Token if the
password matches else return Invalid Password with status code 400.
app.post("/login", async (request, response) => {
const { username, password } = request.body;
const selectUserQuery = `SELECT * FROM user WHERE username = '$
{username}'`;
const dbUser = await db.get(selectUserQuery);
if (dbUser === undefined) {
response.status(400);
response.send("Invalid User");
} else {
const isPasswordMatched = await bcrypt.compare(password, dbUser.password);
if (isPasswordMatched === true) {
const payload = {
username: username,
};
const jwtToken = jwt.sign(payload, "MY_SECRET_TOKEN");
response.send({ jwtToken });
} else {
response.status(400);
response.send("Invalid Password");
}
}
});
We have to add an authorization header to our request and the JWT Token is passed
as a Bearer token
GET http://localhost:3000/books?
offset=2&limit=3&search_q=the&order_by=price&order=DESC
Authorization: bearer
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoicmFodWwiLCJnZW5kZX
IiOiJNYWxlIiwibG9jYXRpb24iOiJoeWRlcmFiYWQiLCJpYXQiOjE2MTc0MzI0M
Dd9.Eqevw5QE70ZAVrmOZUc6pflUbeI0ffZUmQLDHYplU8g
Here we check for JWT Token from Headers. If JWT Token is not present it returns
an Invalid Access Token with status code 401 else verify the JWT Token.
app.get("/books/", (request, response) => {
let jwtToken;
const authHeader = request.headers["authorization"];
if (authHeader !== undefined) {
jwtToken = authHeader.split(" ")[1];
}
if (jwtToken === undefined) {
response.status(401);
response.send("Invalid Access Token");
} else {
jwt.verify(jwtToken, "MY_SECRET_TOKEN", async (error, payload) => {
if (error) {
response.send("Invalid Access Token");
} else {
const getBooksQuery = `
SELECT
*
FROM
book
ORDER BY
book_id;`;
const booksArray = await db.all(getBooksQuery);
response.send(booksArray);
}
});
}
});
Authentication Part 3:
Middleware functions
• Multiple Middleware functions
• Logger Middleware Implementation
• Defining a Middleware Function
• Logger Middleware Function
• Get Books API with Logger Middleware
• Authenticate Token Middleware
• Get Books API with Authenticate Token Middleware
• Passing data from Authenticate Token Middleware
• Get User Profile API with Authenticate Token Middleware
1. Middleware functions
Middleware is a special kind of function in Express JS which accepts the request
from
• the user (or)
• the previous middleware
After processing the request the middleware function
• sends the response to another middleware (or)
• calls the API Handler (or)
• sends response to the user
app.method(Path, middleware1, handler);
Example