0% found this document useful (0 votes)
4 views67 pages

Node JS Basics & Module Exports Guide

This cheat sheet provides an introduction to Node JS, covering key concepts such as the MERN stack, Node JS environment, and how to run JavaScript using Node REPL and CLI. It explains module exports in Node JS, including Common JS and Modern JS (ES6) module exports, detailing how to export and import functions, variables, and classes. The document also includes examples demonstrating default and named exports for both Common JS and ES6 modules.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views67 pages

Node JS Basics & Module Exports Guide

This cheat sheet provides an introduction to Node JS, covering key concepts such as the MERN stack, Node JS environment, and how to run JavaScript using Node REPL and CLI. It explains module exports in Node JS, including Common JS and Modern JS (ES6) module exports, detailing how to export and import functions, variables, and classes. The document also includes examples demonstrating default and named exports for both Common JS and ES6 modules.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Introduction to Node JS | Cheat Sheet:

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

3. Running JavaScript Using Node JS


We can run JavaScript using Node JS in 2 ways.
• Node REPL (Similar to browser console)
• Node CLI

3.1 Node REPL (Read-Eval-Print-Loop)


Type node in the terminal and press Enter.

root@123# node
Welcome to [Link] 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 [Link] v12.18.3.
Type ".help" for more information.
> const a = 1
undefined
> const b = 2
undefined
> a+b
3
> .exit
root@123:/home/workspace#

3.2 Node CLI

We can write JavaScript to a file and can run using Node CLI.

//[Link]

const greetings = (name) => {


[Link](`Hello ${name}`);
};

greetings("Raju");
greetings("Abhi");

Output:

1root@123# node [Link]


2. Hello Raju
3. Hello Abhi

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

4.1 Common JS Module Exports

4.1.1 Default Exports

Exporting Module
The
[Link]
is a special object included in every JavaScript file in the Node JS application by
default.
//[Link]

const add = (a, b) => {


return a + b;
};
[Link] = add;

Importing Module:

To import a module which is the local file, use the require() function with the
relative path of the module (file name).
//[Link]
const add = require("./calculator");
[Link](add(6, 3));
OutPut:
[Link]@123# node [Link]
2. 9

4.1.2 Named Exports


We can have multiple named exports per module.

Exporting Module
//[Link]
const add = (a, b) => {
return a + b;
};
const sub = (a, b) => {
return a - b;
};

[Link] = add;
[Link] = sub;

Importing Module:
//[Link]
const { add, sub } = require("./calculator");
[Link](add(6, 3));
[Link](sub(6, 3));
Output:
root@123# node [Link]
9
3

4.2 Modern JS Module Exports


Modern JS Modules are known as ES6 Modules.
The export and import keywords are introduced for exporting and importing one or
more members in a module.
4.2.1 Default Exports

Exporting Module
//[Link]
const add = (a, b) => {
return a + b;
};
export default add;
Importing Module:

//[Link]

import add from "./[Link]";


[Link](add(6, 3));

OutPut:

root@123# node [Link]


9

4.2.2 Named Exports


Exporting Module

//[Link]

export const add = (a, b) => {


return a + b;
};
export const sub = (a, b) => {
return a - b;
};

Importing Module:

//[Link]

import { add, sub } from "./[Link]";


[Link](add(6, 3));
[Link](sub(6, 3));

Output:

root@123# node [Link]


9
3

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.

Common JS Module Exports | Reading Material:

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:
//[Link]
[Link] = let value = 5;
//[Link]
const num = require("./[Link]");
Output:
root@123# node [Link]
/[Link]
[Link] = let value = 5;
^
SyntaxError: Unexpected identifier
at wrapSafe (internal/modules/cjs/[Link]:16)
...

1.2 Exporting a variable after defining

We can export boolean, number, string, null, undefined, objects, and arrays after
defining.
Example:
//[Link]
let value = 5;
[Link] = value;

//[Link]

const value = require("./[Link]");

[Link](value);

Output:
root@123# node [Link]
5
1.3 Exporting a value or an expression
We can export a value or an expression directly.
Example:
//[Link]
[Link] = 5 * 3;
//[Link]

const result = require("./[Link]");

[Link](result);

Output:

root@123# node [Link]


15

1.4 Exporting a function while defining


We can export a function while defining.
Example:

//[Link]

[Link] = function (num1, num2) {


return num1 + num2;
};

//[Link]

const sum = require("./[Link]");

[Link](sum(2, 6));

Output:

root@123# node [Link]


8

1.5 Exporting a function after defining


We can export a function after defining.
Example:
//[Link]
function sum(num1, num2) {
return num1 + num2;
}
[Link] = sum;
//[Link]

const sum = require("./[Link]");

[Link](sum(2, 6));

Output:

root@123# node [Link]


8

1.6 Exporting a class while defining


We can export a class while defining.
Example:
//[Link]

[Link] = class StudentDetails {


constructor(name, age) {
[Link] = name;
[Link] = age;
}
};

//[Link]

const StudentDetails = require("./[Link]");

const studentDetails = new StudentDetails("Ram", 15);

[Link](studentDetails);

[Link]([Link]);
Output:

root@123# node [Link]


StudentDetails { name: 'Ram', age: 15 }
Ram

1.7 Exporting a class after defining


We can export a class after defining.
Example:
//[Link]

class StudentDetails {
constructor(name, age) {
[Link] = name;
[Link] = age;
}
}
[Link] = StudentDetails;

//[Link]

const StudentDetails = require("./[Link]");

const studentDetails = new StudentDetails("Ram", 15);

[Link](studentDetails);

[Link]([Link]);

Output:

root@123# node [Link]


StudentDetails { name: 'Ram', age: 15 }
Ram

2. Named Exports

2.1 Exporting multiple variables while defining


We cannot export boolean, number, string, null, undefined, objects, and arrays while
defining.
Example:
//[Link]

[Link] = let value = 5;


[Link] = let studentName = "Rahul";

//[Link]

const { value, studentName } = require("./sample");

[Link](value);

[Link](studentName);

Output:

root@123# node [Link]


[Link] = let value = 5;
^^^^^

SyntaxError: Unexpected identifier


at wrapSafe (internal/modules/cjs/[Link]:16)

2.2 Exporting multiple variables after defining


We can export multiple variables after defining.
Example:
//[Link]
let value = 5;
[Link] = value;
let studentName = "Rahul";
[Link] = studentName;
//[Link]

const { value, studentName } = require("./sample");

[Link](value);

[Link](studentName);

Output:
root@123# node [Link]
5
Rahul

2.3 Exporting multiple values and expressions


We can export multiple values and expressions.
Example:
//[Link]
let value = 2;
[Link] = 2 + 3;
[Link] = 3 – value;
//[Link]
const { sum, sub } = require("./sample");
[Link](sum);
[Link](sub);
Output:
root@123# node [Link]
5
1

2.4 Exporting multiple functions while defining


We can export multiple functions while defining.
Example:
//[Link]
[Link] = function (num1, num2) {
return num1 + num2;
};
[Link] = function sub(num1, num2) {
return num1 - num2;
};
//[Link]
const { sum, sub } = require("./sample");
[Link](sum(2, 6));
[Link](sub(8, 3));
Output:
root@123# node [Link]
8
5

2.5 Exporting multiple functions after defining


We can export multiple functions after defining.
Example:
//[Link]

function sum(num1, num2) {


return num1 + num2;
}
[Link] = sum;
function sub(num1, num2) {
return num1 - num2;
}
[Link] = sub;
//[Link]

const { sum, sub } = require("./sample");

[Link](sum(2, 6));

[Link](sub(8, 3));

Output:

root@123# node [Link]


8
5
2.6 Exporting multiple classes while defining
We can export multiple classes while defining.
Example:
//[Link]

[Link] = class StudentDetails {


constructor(name, age) {
[Link] = name;
[Link] = age;
}
};

[Link] = class CarDetails {


constructor(name, age) {
[Link] = name;
[Link] = age;
}
};

//[Link]

const { studentDetails, carDetails } = require("./[Link]");

const newStudentDetails = new studentDetails("Ram", 15);


[Link](newStudentDetails);
[Link]([Link]);

const newCarDetails = new carDetails("Alto", "60kmph");


[Link](newCarDetails);
[Link]([Link]);

Output:

root@123# node [Link]


StudentDetails { name: 'Ram', age: 15 }
Ram
CarDetails { name: 'Alto', speed: '60kmph' }
Alto

2.7 Exporting multiple classes after defining


We can export multiple classes after defining.
Example:
//[Link]

class StudentDetails {
constructor(name, age) {
[Link] = name;
[Link] = age;
}
}
[Link] = StudentDetails;

class CarDetails {
constructor(name, age) {
[Link] = name;
[Link] = age;
}
}

[Link] = CarDetails;

//[Link]

const { studentDetails, carDetails } = require("./[Link]");

const newStudentDetails = new studentDetails("Ram", 15);


[Link](newStudentDetails);
[Link]([Link]);

const newCarDetails = new carDetails("Alto", "60kmph");


[Link](newCarDetails);
[Link]([Link]);

Output:

root@123# node [Link]


StudentDetails { name: 'Ram', age: 15 }
Ram
CarDetails { name: 'Alto', speed: '60kmph' }
Alto

ES6 Module Exports | Reading Material


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 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:

//[Link]

export default let value = 5;

//[Link]

import value from "./[Link]";


[Link](value);

Output:
root@123# node [Link]
(node:31964) ExperimentalWarning: The ESM module loader is experimental.
[Link]
export default let value = 5;
^^^
SyntaxError: Unexpected strict mode reserved word

1.2 Exporting a variable after defining


We can export boolean, number, string, null, undefined, objects, and arrays after
defining.
Example:
//[Link]

let a = 5;
export default a;

//[Link]

import a from "./[Link]";


[Link](a);

Output:
root@123# node [Link]
(node:32665) ExperimentalWarning: The ESM module loader is experimental.
5

1.3 Exporting a value or an expression


We can export a value or an expression directly.
Example:
//[Link]

export default 5 * 3;

//[Link]

import result from "./[Link]";

[Link](result);

Output:

root@123# node [Link]


(node:4071) ExperimentalWarning: The ESM module loader is experimental.
15
1.4 Exporting a function while defining
We can export a function while defining.
Example:
//[Link]

export default function (num1, num2) {


return num1 + num2;
}

//[Link]

import sum from "./[Link]";

[Link](sum(2, 6));

Output:

root@123# node [Link]


(node:4278) ExperimentalWarning: The ESM module loader is experimental.
8

1.5 Exporting a function after defining

We can export a function after defining.


Example:
//[Link]

function sum(num1, num2) {


return num1 + num2;
}
export default sum;

//[Link]

import sum from "./[Link]";


[Link](sum(2, 6));

Output:

root@123# node [Link]


(node:4462) ExperimentalWarning: The ESM module loader is experimental.
8

1.6 Exporting a class while defining

We can export a class while defining.


Example:
//[Link]

export default class StudentDetails {


constructor(name, age) {
[Link] = name;
[Link] = age;
}
}
//[Link]

import StudentDetails from "./[Link]";

const newStudentDetails = new StudentDetails("Ram", 15);


[Link](newStudentDetails);
[Link]([Link]);

Output:

root@123# node [Link]


(node:1035) ExperimentalWarning: The ESM module loader is experimental.
StudentDetails {name: "Ram", age: 15}
Ram

1.7 Exporting a class after defining

We can export a class after defining.


Example:
//[Link]

class StudentDetails {
constructor(name, age) {
[Link] = name;
[Link] = age;
}
}
export default StudentDetails;
//[Link]

import StudentDetails from "./[Link]";

const newStudentDetails = new StudentDetails("Ram", 15);


[Link](newStudentDetails);
[Link]([Link]);

Output:
root@123# node [Link]
(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:
//[Link]

export let value = 5;


export let studentName = "Rahul";

//[Link]

import { value, studentName } from "./[Link]";


[Link](value);

[Link](studentName);

Output:

root@123# node [Link]


(node:1770) ExperimentalWarning: The ESM module loader is experimental.
5
Rahul

2.2 Exporting multiple variables after defining


We can export multiple variables after defining in an Object format.
Example:
//[Link]

let value = 5;
const studentName = "Rahul";

export { value, studentName };

//[Link]

import { value, studentName } from "./[Link]";

[Link](value);
[Link](studentName);

Output:

root@123# node [Link]


(node:2437) ExperimentalWarning: The ESM module loader is experimental.
5
Rahul

2.3 Exporting multiple functions while defining


We can export multiple functions while defining.
Example:
//[Link]
export function sum(num1, num2) {
return num1 + num2;
}

export function sub(num1, num2) {


return num1 - num2;
}

//[Link]

import { sum, sub } from "./[Link]";

[Link](sum(4, 2));

[Link](sub(4, 2));

Output:

root@123# node [Link]


(node:2954) ExperimentalWarning: The ESM module loader is experimental.
6
2

2.4 Exporting multiple functions after defining


We can export multiple functions after defining.
Example:
//[Link]

function sum(num1, num2) {


return num1 + num2;
}

function sub(num1, num2) {


return num1 - num2;
}

export { sum, sub };

//[Link]

import { sum, sub } from "./[Link]";


[Link](sum(4, 2));

[Link](sub(4, 2));

Output:

root@123# node [Link]


(node:3276) ExperimentalWarning: The ESM module loader is experimental.
6
2

2.5 Exporting multiple classes while defining


We can export multiple classes while defining.
Example:
//[Link]

export class StudentDetails {


constructor(name, age) {
[Link] = name;
[Link] = age;
}
}

export class CarDetails {


constructor(name, speed) {
[Link] = name;
[Link] = speed;
}
}

//[Link]

import { StudentDetails, CarDetails } from "./[Link]";

const newStudentDetails = new StudentDetails("Ram", 15);


[Link](newStudentDetails);
[Link]([Link]);

const newCarDetails = new CarDetails("Alto", "60kmph");


[Link](newCarDetails);
[Link]([Link]);

Output:

root@123# node [Link]


(node:3517) ExperimentalWarning: The ESM module loader is experimental.
StudentDetails { name: 'Ram', age: 15 }
Ram
CarDetails { name: 'Alto', speed: '60kmph' }
Alto

2.6 Exporting multiple classes after defining

We can export multiple classes after defining.


Example:
//[Link]

class StudentDetails {
constructor(name, age) {
[Link] = name;
[Link] = age;
}
}

class CarDetails {
constructor(name, speed) {
[Link] = name;
[Link] = speed;
}
}

export { StudentDetails, CarDetails };

//[Link]

import { StudentDetails, CarDetails } from "./[Link]";


const newStudentDetails = new StudentDetails("Ram", 15);
[Link](newStudentDetails);
[Link]([Link]);

const newCarDetails = new CarDetails("Alto", "60kmph");


[Link](newCarDetails);
[Link]([Link]);

Output:

root@123# node [Link]


(node:3841) ExperimentalWarning: The ESM module loader is experimental.
StudentDetails {name: "Ram", age: 15}
Ram
CarDetails {name: "Alto", speed: "60kmph"}
Alto

Introduction to Node JS | Part 2 | Cheat Sheet:


Concepts in Focus
• Core Modules
• Path
• Package
• Node Package Manager (NPM)
• Steps to create a Node JS Project
• Third-Party Packages
• date-fns

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:

const path = require("path");

Example:

//[Link]

const path = require("path");


const filePath = [Link]("users", "ravi", "[Link]");

[Link](filePath);

Output:

root@123# node [Link]


users/ravi/[Link]

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 Node Package Manager (NPM)


NPM is the package manager for the Node JS packages with more than one million
packages.
It provides a command line tool that allows you to publish, discover, install, and
develop node programs.

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
[Link] file
npm install <package-name>
Installs the third-party packages
--save

3. Steps to create a Node JS Project


Run the below commands in the terminal.
1. Create a new directory/folder.
mkdir myapp
2. Move into the created folder.
cd myapp
3. Initialize the project.
npm init -y

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 & [Link].
Installation Command:

npm install date-fns –save

4.1.1 addDays
It adds the specified number of days to the given date.
Example:

//[Link]

const addDays = require("date-fns/addDays");


const result = addDays(new Date(2021, 0, 11), 10);

[Link](result);

Output:

[Link]@123# node [Link]


2.2021-01-21T00:00:00.000Z

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.

Introduction to Express JS | Cheat Sheet

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

1.1 Server-side Web Frameworks


The Server-side Web Frameworks take care of all the above requirements.
Some of the Web Frameworks are:
• Express (Node JS)
• Django (Python)
• Ruby on Rails (Ruby)
• Spring Boot (Java)

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

3. Network call using Express JS


1. Creating Express server instance
const express = require("express");
const app = express();
2. Assigning a port number
[Link](3000);

3.1 Handling HTTP Request


Syntax:
[Link](PATH, HANDLER)
• METHOD is an HTTP request method, in lowercase like get , post , put , and
delete.
• PATH is a path on the server.
• HANDLER is the function executed when the PATH is matched with the
requested path.

3.1.1 GET Request

const express = require("express");


const app = express();

[Link]("/", (request, response) => {


[Link]("Hello World!");
});
[Link](3000);

Note:
Whenever the code changes, we need to restart the server to reflect the changes we
made.

4. Testing Network Calls


We can test the Network calls in two ways.
1. Browser Network Tab.
1. Clicking the Send Request in the [Link] file.
5. Network Call to get a Today’s Date

const express = require("express");


const app = express();
[Link]("/date", (request, response) => {
let date = new Date();
[Link](`Today's date is ${date}`);
});
[Link](3000);

6. Network Call to get HTML content as an HTTP Response


6.1 Sending file as an HTTP Response
Syntax:
[Link](PATH, {root: __dirname });
• PATH is a path to the file which we want to send.
• __dirname is a variable in Common JS Modules that returns the path of the
folder where the current JavaScript file is present.
const express = require("express");
const app = express();
[Link]("/page", (request, response) => {
[Link]("./[Link]", { root: __dirname });
});
[Link](3000);
Introduction to Express JS | Part 2
Concepts in Focus
• Application Programming Interface (API)
• Database
• SQLite
• SQLite CLI
• SQLite Methods
• Open
• Executing SQL Queries
• SQL Third-party packages
• Connecting SQLite Database from Node JS to get the books from Goodreads
Website
• SQLite Database Initialization
• Goodreads Get Books API

1. Application Programming Interface (API)

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.

3.1 SQLite CLI

3.1.1 Listing Existing Tables


The
.tables
command is used to get the list of tables available in the SQLite database.
3.1.2 Selecting Table Data
Syntax:
SELECT * from <table>

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()
[Link](SQL_QUERY);
The
all()
method is used to get multiple rows of data.

5. SQL Third-party packages


We can use
sqlite
and
sqlite3
node packages to connect SQLite Database from Node JS.
Installation Commands
npm install sqlite --save
npm install sqlite3 –save

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

6.1 SQLite Database Initialization

const express = require("express");


const path = require("path");
const { open } = require("sqlite");
const sqlite3 = require("sqlite3");
const app = express();
const dbPath = [Link](__dirname, "[Link]");
let db = null;
const initializeDBAndServer = async () => {
try {
db = await open({
filename: dbPath,
driver: [Link],
});
[Link](3000, () => {
[Link]("Server Running at [Link]
});
} catch (e) {
[Link](`DB Error: ${[Link]}`);
[Link](1);
}
};
initializeDBAndServer();

6.2 Goodreads Get Books API


[Link]("/books/", async (request, response) => {
const getBooksQuery = `
SELECT
*
FROM
book
ORDER BY
book_id;`;
const booksArray = await [Link](getBooksQuery);
[Link](booksArray);
});

Introduction to Express JS | Part 3

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:
[Link](SQL_QUERY);

1.2 run()
The
run()
method is used to create or update table data.
Syntax:
[Link](SQL_QUERY);

2. Node JS Third-party packages

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
[Link].

3. GoodReads APIs
• Get Book
• Add Book
• Update Book
• Delete Book
• Get Author Books

3.1 Get Book


We can use
/books/:bookId/
as a path to identify a single book resource, where
bookId
is a path parameter.
For example,
In [Link] , the bookId is 1.

[Link]("/books/:bookId/", async (request, response) => {


const { bookId } = [Link];
const getBookQuery = `
SELECT
*
FROM
book
WHERE
book_id = ${bookId};`;
const book = await [Link](getBookQuery);
[Link](book);
});

Note: Any String can be used a Path Parameter.

3.2 Add Book


To add a book to the Database, you need to send a request body in JSON format.
• The [Link]() is used to recognize the incoming request object as JSON
Object and parses it.
• The [Link] is used to get the HTTP Request body.

[Link]("/books/", async (request, response) => {


const bookDetails = [Link];
const {
title,
authorId,
rating,
ratingCount,
reviewCount,
description,
pages,
dateOfPublication,
editionLanguage,
price,
onlineStores,
} = bookDetails;
const addBookQuery = `
INSERT INTO
book
(title,author_id,rating,rating_count,review_count,description,pages,date_of_publicati
on,edition_language,price,online_stores)
VALUES
(
'${title}',
${authorId},
${rating},
${ratingCount},
${reviewCount},
'${description}',
${pages},
'${dateOfPublication}',
'${editionLanguage}',
${price},
'${onlineStores}'
);`;

const dbResponse = await [Link](addBookQuery);


const bookId = [Link];
[Link]({ bookId: bookId });
});

The
[Link]
provides the primary key of the new row inserted.

3.3 Update Book


We can use books/:bookId/ as a path to identify a single book resource,
where :bookId is the path parameter.
For example,
[Link]

[Link]("/books/:bookId/", async (request, response) => {


const { bookId } = [Link];
const bookDetails = [Link];
const {
title,
authorId,
rating,
ratingCount,
reviewCount,
description,
pages,
dateOfPublication,
editionLanguage,
price,
onlineStores,
} = bookDetails;
const updateBookQuery = `
UPDATE
book
SET
title='${title}',
author_id=${authorId},
rating=${rating},
rating_count=${ratingCount},
review_count=${reviewCount},
description='${description}',
pages=${pages},
date_of_publication='${dateOfPublication}',
edition_language='${editionLanguage}',
price=${price},
online_stores='${onlineStores}'
WHERE
book_id = ${bookId};`;
await [Link](updateBookQuery);
[Link]("Book Updated Successfully");
});

The [Link] provides the parameters passed through the request.

Note: The strings sent through the APIs must be wrapped in quotes.
3.4 Delete Book

[Link]("/books/:bookId/", async (request, response) => {


const { bookId } = [Link];
const deleteBookQuery = `
DELETE FROM
book
WHERE
book_id = ${bookId};`;
await [Link](deleteBookQuery);
[Link]("Book Deleted Successfully");
});

3.5 Get Author Books

[Link]("/authors/:authorId/books/", async (request, response) => {


const { authorId } = [Link];
const getAuthorBooksQuery = `
SELECT
*
FROM
book
WHERE
author_id = ${authorId};`;
const booksArray = await [Link](getAuthorBooksQuery);
[Link](booksArray);
});

REST APIs

Concepts in Focus
• Get Books API
• Filtering Books
• REST APIs
• Why Rest Principles?
• REST API Principles

1. Get Books API


Let's see how to add Filters to Get Books API
1.1 Filtering Books
• Get a specific number of books
• Get books based on search query text
• Get books in the sorted order

1.1.1 Get a specific number of books


To get specific number of books in certain range we use limit and offset.
Offset is used to specify the position from where rows are to be selected.
Limit is used to specify the number of rows. and many more... Query parameters
starts with ? (question mark) followed by key value pairs separated by &
(ampersand)
Example :
[Link]

[Link]

[Link]

Note :

The query parameters are used to sort/filter resources.


The path parameters are used to identify a specific resource(s)

1.1.2 Get books based on search query text

We provide query text to search_q key


search_q = potter

1.1.3 Get books in the sorted order


We provide sorted order to order key
Ascending: ASC DESCENDING: DESC
order = ASC
order = DESC

Filtering GET Books API

[Link]("/books/", async (request, response) => {


const {
offset = 2,
limit = 5,
order = "ASC",
order_by = "book_id",
search_q = "",
} = [Link];
const getBooksQuery = `
SELECT
*
FROM
book
WHERE
title LIKE '%${search_q}%'
ORDER BY ${order_by} ${order}
LIMIT ${limit} OFFSET ${offset};`;
const booksArray = await [Link](getBooksQuery);
[Link](booksArray);
});

Note:
We can skip or add slash while appending query parameters to the URL
[Link]
is same as
[Link]

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.

2.1 Why Rest Principles?


Using Rest Principles improves application in various aspects like scalability,
reliability etc

2.2 REST API Principles


• Providing unique ID to each resource
• Using standard methods like GET, POST, PUT, and DELETE
• Accept and Respond with JSON
and many more...
Debugging Common Errors

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

1. Importing Unknown Modules


When we try to import unknown modules
root@123:/.../myapp# nodemon [Link]
[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 [Link]`
internal/modules/cjs/[Link]
throw err;
^
Error: Cannot find module 'expresses'
Require stack:
- /home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/myapp/[Link]
at [Link]._resolveFilename (internal/modules/cjs/[Link]:15)
at [Link]._load (internal/modules/cjs/[Link]:27)
at [Link] (internal/modules/cjs/[Link]:19)
at require (internal/modules/cjs/[Link]:18)
at Object.<anonymous> (/home/workspace/nodejs/sessions/Introduction-to-
Express-JS-Part-2/myapp/[Link]:17)
at Module._compile (internal/modules/cjs/[Link]:30)
at [Link]._extensions..js (internal/modules/cjs/[Link]:10)
at [Link] (internal/modules/cjs/[Link]:32)
at [Link]._load (internal/modules/cjs/[Link]:14)
at [Link] [as runMain]
(internal/modules/run_main.js:71:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/myapp/
[Link]'
]
}
[nodemon] app crashed - waiting for file changes before starting...

2. Starting Server in Multiple Terminals


When we try to start the server in multiple terminals
root@123:/.../myapp# nodemon [Link]
[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 [Link]`
[Link]
throw er; // Unhandled 'error' event
^

Error: listen EADDRINUSE: address already in use :::3000


at [Link] [as _listen2] ([Link]:16)
at listenInCluster ([Link]:12)
at [Link] ([Link]:7)
at [Link] (/home/workspace/nodejs/sessions/Introduction-to-Express-JS-
Part-2/myapp/node_modules/.pnpm/express@4.17.1/node_modules/express/lib/
[Link]:24)
at initializeDBAndServer (/home/workspace/nodejs/sessions/Introduction-to-
Express-JS-Part-2/myapp/[Link]:9)
Emitted 'error' event on Server instance at:
at emitErrorNT ([Link]:8)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
code: 'EADDRINUSE',
errno: 'EADDRINUSE',
syscall: 'listen',
address: '::',
port: 3000
}
[nodemon] app crashed - waiting for file changes before starting...
When you get address already in use :::3000 error
Step 1: Kill the currently running process in the terminal with Ctrl + C
Step 2: Run lsof -i :port_number in your CCBP IDE Terminal

Step 3: Run kill -9 process_id in your CCBP IDE Terminal


Example :
root@123:/.../...part-3/myapp# nodemon [Link]
[nodemon] starting `node [Link]`
[Link]
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE: address already in use :::3000
.
.
.
^C

root@123:/.../...part-3# lsof -i :3000

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME


node 9841 root 20u IPv6 345981 0t0 TCP *:3000 (LISTEN)

root@123:/.../...part-3# kill -9 9841


root@123:/.../...part-3#

3. Starting Server outside the myapp


When we try to start the server outside myapp using node

root@123:/.../...part-3# node [Link]


internal/modules/cjs/[Link]
throw err;
^
Error: Cannot find module '/.../...Part-3/[Link]'
root@123:/.../...part-3#

When we try to start the server outside myapp using nodemon


root@123:/.../...part-3# nodemon [Link]
Usage: nodemon [nodemon options] [[Link]] [args]
See "nodemon --help" for more.
root@123:/.../...part-3#

4. Accessing Wrong URL


When we try to Send Request for wrong URLs
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 /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 [Link]
[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 [Link]`
/home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/myapp/
[Link]
[Link]("/books/", async (request, response) => {
^

TypeError: [Link] is not a function


at Object.<anonymous> (/home/workspace/nodejs/sessions/Introduction-to-
Express-JS-Part-2/myapp/[Link]:5)
at Module._compile (internal/modules/cjs/[Link]:30)
at [Link]._extensions..js (internal/modules/cjs/[Link]:10)
at [Link] (internal/modules/cjs/[Link]:32)
at [Link]._load (internal/modules/cjs/[Link]:14)
at [Link] [as runMain]
(internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
[nodemon] app crashed - waiting for file changes before starting...

6. Importing Unknown File


When we try to import an unknown file
root@123:/.../...part-3/myapp# nodemon [Link]
[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 [Link]`
Server Running at [Link]
(node:668) UnhandledPromiseRejectionWarning: Error: SQLITE_ERROR: no such
table: book
(node:668) 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
[Link] (rejection id: 1)
(node:668) [DEP0018] DeprecationWarning: Unhandled promise rejections are
deprecated. In the future, promise rejections that are not handled will terminate the
[Link] process with a non-zero exit code.
Debugging Common Errors | Part 2

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(:)

When we miss semicolon while setting Path 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 /books/</pre>
</body>
</html>

3. Accessing Path Parameters


When we are trying to access path parameters with the wrong name
root@123:/.../...part-3/myapp# nodemon [Link]
[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 [Link]`
Server Running at [Link]
(node:905) UnhandledPromiseRejectionWarning: ReferenceError: bookId is not
defined
at /home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/myapp/
[Link]:19
at [Link] [as handle_request]
(/home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/myapp/
node_modules/.pnpm/express@4.17.1/node_modules/express/lib/router/[Link]:5)
at next (/home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/
myapp/node_modules/.pnpm/express@4.17.1/node_modules/express/lib/router/
[Link]:13)
at [Link] (/home/workspace/nodejs/sessions/Introduction-to-Express-JS-
Part-2/myapp/node_modules/.pnpm/express@4.17.1/node_modules/express/lib/
router/[Link]:3)
at [Link] [as handle_request]
(/home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/myapp/
node_modules/.pnpm/express@4.17.1/node_modules/express/lib/router/[Link]:5)
at /home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/myapp/
node_modules/.pnpm/express@4.17.1/node_modules/express/lib/router/
[Link]:22
at param (/home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/
myapp/node_modules/.pnpm/express@4.17.1/node_modules/express/lib/router/
[Link]:14)
at param (/home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/
myapp/node_modules/.pnpm/express@4.17.1/node_modules/express/lib/router/
[Link]:14)
at Function.process_params (/home/workspace/nodejs/sessions/Introduction-to-
Express-JS-Part-2/myapp/node_modules/.pnpm/express@4.17.1/node_modules/
express/lib/router/[Link]:3)
at next (/home/workspace/nodejs/sessions/Introduction-to-Express-JS-Part-2/
myapp/node_modules/.pnpm/express@4.17.1/node_modules/express/lib/router/
[Link]:10)
(node:905) 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
[Link] (rejection id: 1)
(node:905) [DEP0018] DeprecationWarning: Unhandled promise rejections are
deprecated. In the future, promise rejections that are not handled will terminate the
[Link] process with a non-zero exit code.

4. Query Formatting
When we miss embedding expression into string literal properly in the query
root@123:/.../...part-3/myapp# nodemon [Link]
[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 [Link]`
Server Running at [Link]
(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
[Link] (rejection id: 1)
(node:1023) [DEP0018] DeprecationWarning: Unhandled promise rejections are
deprecated. In the future, promise rejections that are not handled will terminate the
[Link] process with a non-zero exit code.

5. Replacing SQLite Methods


When we use one SQLite method instead of another SQLite method we may get an
unexpected response
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 34
ETag: W/"22-fiAy4921oZAEOAA97wnoLQyL2Dw"
Date: Sun, 04 Apr 2021 12:46:07 GMT
Connection: close

{
"stmt":{},
"lastID":0,
"changes":0
}

6. HTTP Request URL

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
[Link]
der=DESC</pre>
</body>
</html>
6.2 Missing & between Query Parameters

When we miss & between query parameters

root@123:/.../...part-3/myapp# nodemon [Link]


[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 [Link]`
Server Running at [Link]
string
(node:1408) UnhandledPromiseRejectionWarning: Error: SQLITE_ERROR:
unrecognized token: "3offset"
(node:1408) 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
[Link] (rejection id: 1)
(node:1408) [DEP0018] DeprecationWarning: Unhandled promise rejections are
deprecated. In the future, promise rejections that are not handled will terminate the
[Link] process with a non-zero exit code.

6.3 Replacing & with , in Query Parameters

When we replace & with , in Query Parameters

root@123:/.../...part-3/myapp# nodemon [Link]


[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 [Link]`
Server Running at [Link]
string
(node:1452) UnhandledPromiseRejectionWarning: Error: SQLITE_ERROR: near ",":
syntax error
(node:1452) 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
[Link] (rejection id: 1)
(node:1452) [DEP0018] DeprecationWarning: Unhandled promise rejections are
deprecated. In the future, promise rejections that are not handled will terminate the
[Link] process with a non-zero exit code.

7. Accessing Unknown Database


When we are trying to access an unknown Database it will not show any error instead
it creates a new database with the given name
root@123:/.../myapp# sqlite3 [Link]
SQLite version 3.16.2 2017-01-06 16:32:41
Enter ".help" for usage hints.
sqlite>.tables
sqlite>

8. Accessing Wrong Port Number

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
[Link]:4000.

Authentication:

Concepts in Focus

• Installing Third-party package bcrypt


• Goodreads APIs for Specified Users
• Register User API
• Login User API

1. Installing Third-party package bcrypt


Storing the passwords in plain text within a database is not a good idea since they can
be misused, So Passwords should be encrypted
bcrypt
package provides functions to perform operations like encryption, comparison, etc
• [Link]() uses various processes and encrypts the given password and
makes it unpredictable
• [Link]() function compares the password entered by the user and
hash against each other
Installation Command
root@123:~/myapp# npm install bcrypt --save
2. Goodreads APIs for Specified Users
We need to maintain the list of users in a table and provide access only to that
specified users
User needs to be registered and then log in to access the books
• Register User API
• Login User API

2.1 Register User API


Here we check whether the user is a new user or an existing user. Returns "User
Already exists" for existing user else for a new user we store encrypted password in
the DB
[Link]("/users/", async (request, response) => {
const { username, name, password, gender, location } = [Link];
const hashedPassword = await [Link]([Link], 10);
const selectUserQuery = `SELECT * FROM user WHERE username = '$
{username}'`;
const dbUser = await [Link](selectUserQuery);
if (dbUser === undefined) {
const createUserQuery = `
INSERT INTO
user (username, name, password, gender, location)
VALUES
(
'${username}',
'${name}',
'${hashedPassword}',
'${gender}',
'${location}'
)`;
const dbResponse = await [Link](createUserQuery);
const newUserId = [Link];
[Link](`Created new user with ${newUserId}`);
} else {
[Link] = 400;
[Link]("User already exists");
}
});

2.2 Login User API


Here we check whether the user exists in DB or not. Returns "Invalid User" if the
user doesn't exist else we compare the given password with the DB user password
[Link]("/login", async (request, response) => {
const { username, password } = [Link];
const selectUserQuery = `SELECT * FROM user WHERE username = '$
{username}'`;
const dbUser = await [Link](selectUserQuery);
if (dbUser === undefined) {
[Link](400);
[Link]("Invalid User");
} else {
const isPasswordMatched = await [Link](password, [Link]);
if (isPasswordMatched === true) {
[Link]("Login Success!");
} else {
[Link](400);
[Link]("Invalid Password");
}
}
});
Status Codes:
Status Codes Status Text ID
200 OK
204 No Response
301 Moved Permanently
400 Bad Request
403 Forbidden
401 Unauthorized

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

2. Token Authentication mechanism


We use the Access Token to verify whether the user is logged in or not

2.1 Access Token


Access Token is a set of characters which are used to identify a user
Example:
It is used to verify whether a user is Valid/Invalid
2.2 How Token Authentication works?
• Server generates token and certifies the client
• Client uses this token on every subsequent request
• Client don’t need to provide entire details every time

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

3.1 How JWT works?


Client: Login with username and password Server: Returns a JWT Token Client:
Sends JWT Token while requesting Server: Sends Response to the client

3.2 JWT Package


Jsonwebtoken package provides [Link] and [Link] functions
• [Link]() function takes payload, secret key, options as arguments and
generates JWTToken out of it
• [Link]() verifies jwtToken and if it’s valid, returns payload. Else, it throws
an error

root@123root@123:.../myapp# npm install jsonwebtoken

4. Login User API by generating the 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.
[Link]("/login", async (request, response) => {
const { username, password } = [Link];
const selectUserQuery = `SELECT * FROM user WHERE username = '$
{username}'`;
const dbUser = await [Link](selectUserQuery);
if (dbUser === undefined) {
[Link](400);
[Link]("Invalid User");
} else {
const isPasswordMatched = await [Link](password, [Link]);
if (isPasswordMatched === true) {
const payload = {
username: username,
};
const jwtToken = [Link](payload, "MY_SECRET_TOKEN");
[Link]({ jwtToken });
} else {
[Link](400);
[Link]("Invalid Password");
}
}
});

5. How to pass JWT Token?

We have to add an authorization header to our request and the JWT Token is passed
as a Bearer token
GET [Link]
offset=2&limit=3&search_q=the&order_by=price&order=DESC
Authorization: bearer
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoicmFodWwiLCJnZW5kZX
IiOiJNYWxlIiwibG9jYXRpb24iOiJoeWRlcmFiYWQiLCJpYXQiOjE2MTc0MzI0M
Dd9.Eqevw5QE70ZAVrmOZUc6pflUbeI0ffZUmQLDHYplU8g

6. Get Books API with Token Authentication

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.
[Link]("/books/", (request, response) => {
let jwtToken;
const authHeader = [Link]["authorization"];
if (authHeader !== undefined) {
jwtToken = [Link](" ")[1];
}
if (jwtToken === undefined) {
[Link](401);
[Link]("Invalid Access Token");
} else {
[Link](jwtToken, "MY_SECRET_TOKEN", async (error, payload) => {
if (error) {
[Link]("Invalid Access Token");
} else {
const getBooksQuery = `
SELECT
*
FROM
book
ORDER BY
book_id;`;
const booksArray = await [Link](getBooksQuery);
[Link](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
[Link](Path, middleware1, handler);

Example

const jsonMiddleware = [Link]();


[Link](jsonMiddleware);

It is a built-in middleware function it recognizes the incoming request object as a


JSON object, parses it, and then calls handler in every API call
1.1 Multiple Middleware functions
We can pass multiple middleware functions
[Link](Path, middleware1, middleware2, handler);

2. Logger Middleware Implementation


2.1 Defining a Middleware Function
const middlewareFunction = (request, response, next) => {};

2.2 Logger Middleware Function


const logger = (request, response, next) => {
[Link]([Link]);
next();
};
The next parameter is a function passed by Express JS which, when invoked,
executes the next succeeding function
2.3 Get Books API with Logger Middleware
[Link]("/books/", logger, async (request, response) => {
const getBooksQuery = `
SELECT
*
FROM
book
ORDER BY
book_id;`;
const booksArray = await [Link](getBooksQuery);
[Link](booksArray);
});

3. Authenticate Token Middleware


In Authenticate Token Middleware we will verify the JWT Token
const authenticateToken = (request, response, next) => {
let jwtToken;
const authHeader = [Link]["authorization"];
if (authHeader !== undefined) {
jwtToken = [Link](" ")[1];
}
if (jwtToken === undefined) {
[Link](401);
[Link]("Invalid JWT Token");
} else {
[Link](jwtToken, "MY_SECRET_TOKEN", async (error, payload) => {
if (error) {
[Link](401);
[Link]("Invalid JWT Token");
} else {
next();
}
});
}
};

4. Get Books API with Authenticate Token Middleware


Let's Pass Authenticate Token Middleware to Get Books API

[Link]("/books/", authenticateToken, async (request, response) => {


const getBooksQuery = `
SELECT
*
FROM
book
ORDER BY
book_id;`;
const booksArray = await [Link](getBooksQuery);
[Link](booksArray);
});

5. Passing data from Authenticate Token Middleware


We cannot directly pass data to the next handler, but we can send data through the
request object
const authenticateToken = (request, response, next) => {
let jwtToken;
const authHeader = [Link]["authorization"];
if (authHeader !== undefined) {
jwtToken = [Link](" ")[1];
}
if (jwtToken === undefined) {
[Link](401);
[Link]("Invalid JWT Token");
} else {
[Link](jwtToken, "MY_SECRET_TOKEN", async (error, payload) => {
if (error) {
[Link](401);
[Link]("Invalid JWT Token");
} else {
[Link] = [Link];
next();
}
});
}
};

6. Get User Profile API with Authenticate Token Middleware


We can access request variable from the request object
[Link]("/profile/", authenticateToken, async (request, response) => {
let { username } = request;
const selectUserQuery = `SELECT * FROM user WHERE username = '$
{username}'`;
const userDetails = await [Link](selectUserQuery);
[Link](userDetails);
});

You might also like