Saturday, July 4, 2020

How to create Node JS Basic Routing

1. Reference: https://github.com/acad1. Create project folder
------------------------
malex@WINDOWS-1J3BS7A MINGW64 /
$ cd ~

malex@WINDOWS-1J3BS7A MINGW64 ~
$ cd node-tutorial/

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial
$ ls -l
total 8
drwxr-xr-x 1 malex 197121 0 Jul  4 11:56 node-pgsql/
drwxr-xr-x 1 malex 197121 0 Jul  4 12:35 node-rest-shop/

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial
$ mkdir -p node-rest-shop-basic-router/api/routes

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial
$ cd node-rest-shop-basic-router/

2. Initialize the project
-------------------------
malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install ` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (rest-shop-basic-router)
version: (1.0.0)
description: A Node.js RESTful API Tutorial Project (Build a simple shop API)
entry point: (index.js) server.js
test command:
git repository:
keywords:
author: Alex Madriaga
license: (ISC)
About to write to C:\Users\malex\node-tutorial\node-rest-shop-basic-router\packa
ge.json:

{
  "name": "rest-shop-basic-router",
  "version": "1.0.0",
  "description": "A Node.js RESTful API Tutorial Project (Build a simple shop API)",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Alex Madriaga",
  "license": "ISC"
}


Is this OK? (yes) yes

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$

3. Create the server.js
-----------------------
malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ touch server.js

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ vi server.js

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ cat server.js

const app = require('./app');
const port = process.env.PORT || 3700;

// 0. default root
app.get("/",async (req,res, next) => {
    try{
      res.send("Welcome to Node REST Shop Basic Router Application");
    } catch(error){
       console.error(error.message);
    }
});

app.listen(port,()=> {
    console.log("Server is listening on port :",port);
});

4. Create the app.js
-----------------------
malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ touch app.js

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ vi app.js

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ cat app.js

const express = require("express");
const app = express();
const productRoutes = require('./api/routes/products');
const orderRoutes = require('./api/routes/orders.js');

app.use('/products', productRoutes);
app.use('/orders', orderRoutes);

module.exports = app;

5. Create orders routes
-----------------------

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ touch api/routes/orders.js

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ vi api/routes/orders.js

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ cat api/routes/orders.js

const express = require('express');
const router = express.Router();

router.get('/', (req, res, next) => {
    res.status(200).json({
        message: 'Orders were fetched'
    });
});

router.post('/', (req, res, next) => {
    res.status(201).json({
        message: 'Order was created'
    });
});

router.get('/:orderId', (req, res, next) => {
    res.status(200).json({
        message: 'Order details',
        orderId: req.params.orderId
    });
});

router.delete('/:orderId', (req, res, next) => {
    res.status(200).json({
        message: 'Order deleted',
        orderId: req.params.orderId
    });
});

module.exports = router;

6. Create products routes
-------------------------
malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ touch api/routes/products.js

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ vi api/routes/products.js

malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ cat api/routes/products.js

const express = require('express');
const router = express.Router();

router.get('/', (req, res, next) => {
    res.status(200).json({
        message: 'Handling GET requests to /products'
    });
});

router.post('/', (req, res, next) => {
    res.status(201).json({
        message: 'Handling POST requests to /products'
    });
});

router.get('/:productId', (req, res, next) => {
    const id = req.params.productId;
    if (id === 'special') {
        res.status(200).json({
            message: 'You discovered the special ID',
            id: id
        });
    } else {
        res.status(200).json({
            message: 'You passed an ID'
        });
    }
});

router.patch('/:productId', (req, res, next) => {
    res.status(200).json({
        message: 'Updated product!'
    });
});

router.delete('/:productId', (req, res, next) => {
    res.status(200).json({
        message: 'Deleted product!'
    });
});

module.exports = router;

7. Install express module
-------------------------
malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ npm i express -s
+ express@4.17.1
added 50 packages from 37 contributors and audited 50 packages in 2.131s
found 0 vulnerabilities

8. Install morgan module
-------------------------
malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ npm i morgan -s
+ morgan@1.10.0
added 4 packages from 2 contributors and audited 54 packages in 1.286s
found 0 vulnerabilities

9. Install nodemon module
-------------------------
malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ npm i nodemon -s
+ nodemon@2.0.4
added 118 packages from 54 contributors and audited 173 packages in 7.435s

8 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities


10. View updated package.json
----------------------------
malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-router
$ cat package.json

{
  "name": "rest-shop-basic-router",
  "version": "1.0.0",
  "description": "A Node.js RESTful API Tutorial Project (Build a simple shop API)",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Alex Madriaga",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "morgan": "^1.10.0",
    "nodemon": "^2.0.4"
  }
}


11. Run the node js application
-------------------------------
malex@WINDOWS-1J3BS7A MINGW64 ~/node-tutorial/node-rest-shop-basic-rc-router
$ nodemon index.js

12. Open browser at htpp://localhost:3700
-----------------------------------------

Friday, July 3, 2020

How to allow access Angular outside localhost:4200

How to allow access outside localhost

1. view open port
[root@thermalite ~]# firewall-cmd --list-ports
9000/tcp 9001/tcp 1433/tcp 8080/tcp 5000/tcp

[root@thermalite ~]# firewall-cmd --permanent --add-port 4200/tcp
success

[root@thermalite ~]# systemctl restart firewalld

[root@thermalite ~]# firewall-cmd --list-ports
9000/tcp 9001/tcp 1433/tcp 8080/tcp 5000/tcp 4200/tcp

[malex@thermalite hello-world]$ ng serve --host 0.0.0.0
Your global Angular CLI version (10.0.1) is greater than your local
version (10.0.0). The local Angular CLI version is used.

To disable this warning use "ng config -g cli.warnings.versionMismatch false".
WARNING: This is a simple server for use in testing or debugging Angular applications
locally. It hasn't been reviewed for security issues.

Binding this server to an open connection can result in compromising your application or
computer. Using a different host than the one passed to the "--host" flag might result in
websocket connection issues. You might need to use "--disableHostCheck" if that's the
case.

chunk {main} main.js, main.js.map (main) 57.7 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 141 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 6.15 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 12.4 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 2.41 MB [initial] [rendered]
Date: 2020-07-03T18:38:33.009Z - Hash: 1c609b822fe9cba12387 - Time: 6023ms
** Angular Live Development Server is listening on 0.0.0.0:4200, open your browser on http://localhost:4200/ **
: Compiled successfully.



Open browser: http://192.168.1.100:4200

How to create a basic PostgreSQL and Node JS Application

1. Create the project folder
--------------------------------
[malex@thermalite node-pgsql]$ mkdir node-pgsql

[malex@thermalite node-pgsql]$ cd node-pgsql

[malex@thermalite node-pgsql]$ npm init -y

2. create the database and table on PostgreSQL
--------------------------------------------------------
[malex@thermalite node-pgsql]$ cat database.sql
-- 1. create database
CREATE DATABASE todo_database;

-- 2. connect to database
\c todo_database

-- 3. create table
CREATE TABLE todo(
  todo_id SERIAL PRIMARY KEY,
  description VARCHAR(255)
);


3. Add npm libraries
-------------------------
[malex@thermalite node-pgsql]$ npm i express -s

[malex@thermalite node-pgsql]$ npm i pg -s

[malex@thermalite node-pgsql]$ npm i nodemon -s

4. create connection configuration
------------------------------------------
[malex@thermalite node-pgsql]$ cat dbpgsql.js
const Pool = require("pg").Pool;

const pool = new Pool({
    user: "postgres",
    password: "pfa_user",
    database: "todo_database",
    host: "192.168.1.100",
    port: 5432
});

module.exports = pool;

5. create the index.js
--------------------------
[malex@thermalite node-pgsql]$ cat index.js
const express = require("express");
const app = express();
const pool = require("./dbpgsql");
const port = 5000;

app.use(express.json()) // -> req.body

// ROUTES//

// 0. default root
app.get("/",async (req,res) => {
try{
  res.send("Welcome to PostgreSQL Node Application");
} catch(error){
   console.error(error.message);
}

});

// 1. get all todos
app.get("/todos",async (req,res) => {
    try {
        const allTodos = await pool.query("SELECT * FROM todo");
        res.json(allTodos.rows);
    } catch (error) {
        console.error(error.message);
    }
});

// 2. get a todo
app.get("/todos/:id",async (req,res) => {
    const { id } = req.params;
    try {
        const todo = await pool.query("SELECT * FROM todo WHERE todo_id = $1", [id]);
        res.json(todo.rows[0]);
    } catch (error) {
        console.error(error.message);
    }
});

// 3. create a todo
app.post("/todos",async (req,res) => {
    try {
        const { description } = req.body;
        const newTodo = await pool.query("INSERT INTO todo (description) VALUES ($1) RETURNING *",
        [description]
        );
        res.json(newTodo);
    } catch (error) {
        console.error(error.message);
    }
});

// 4. update a todo
app.put("/todos/:id",async (req,res) => {
    try {
        const { id } = req.params; // WHERE
        const { description } = req.body; //SET

        const updateTodo = await pool.query("UPDATE todo SET description=$1 WHERE todo_id=$2",
        [description, id]
        );
        res.json("Todo was successfully updated.");
    } catch (error) {
        console.error(error.message);
    }
});

// 5. delete a todo
app.delete("/todos/:id",async (req,res) => {
    try {
        const { id } = req.params; // WHERE

        const deleteTodo = await pool.query("DELETE FROM todo WHERE todo_id=$1",
        [id]
        );
        res.json("Todo was successfully deleted.");
    } catch (error) {
        console.error(error.message);
    }
});

app.listen(port,()=> {
    console.log("Server is listening on port: ", port);
});

6. run the application
[malex@thermalite node-pgsql]$ nodemon index


7. open browser and got to http://192.168.1.100:5000/todos

How to open port 5000 for use by Node JS Application

How to open port 5000 for use by Node JS Application
Reference: https://www.cyberciti.biz/faq/howto-rhel-linux-open-port-using-iptables/

[root@thermalite ~]# firewall-cmd --list-ports
9000/tcp 9001/tcp 1433/tcp 8080/tcp

[root@thermalite ~]# firewall-cmd --get-zones
block dmz drop external home internal libvirt public trusted work

[root@thermalite ~]# ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp2s0: mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 90:2b:34:38:27:51 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.100/24 brd 192.168.1.255 scope global noprefixroute enp2s0
       valid_lft forever preferred_lft forever
    inet6 fe80::3033:b8ea:8652:3d3/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: virbr0: mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:41:41:60 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:41:41:60 brd ff:ff:ff:ff:ff:ff
5: docker0: mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:82:0e:78:5f brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:82ff:fe0e:785f/64 scope link
       valid_lft forever preferred_lft forever

[root@thermalite ~]# firewall-cmd --get-zone-of-interface=enp2s0
public

[root@thermalite ~]# firewall-cmd --permanent --add-port 5000/tcp
success

[root@thermalite ~]# firewall-cmd --list-ports
9000/tcp 9001/tcp 1433/tcp 8080/tcp

[root@thermalite ~]# systemctl restart firewalld

[root@thermalite ~]# firewall-cmd --list-ports
9000/tcp 9001/tcp 1433/tcp 8080/tcp 5000/tcp
[root@thermalite ~]#

Connect to a MongoDB Database Using Node.js

1. Reference: https://www.mongodb.com/blog/post/quick-start-nodejs-mongodb--how-to-get-connected-to-your-database

2. Session
[malex@thermalite mongodb-atlas-client]$ ls -l
total 0
[malex@thermalite mongodb-atlas-client]$ npm init -y
Wrote to /home/malex/nodejs/mongodb-atlas-client/package.json:

{
  "name": "mongodb-atlas-client",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}


[malex@thermalite mongodb-atlas-client]$ npm i mongodb -s
+ mongodb@3.5.9
added 20 packages from 11 contributors and audited 20 packages in 1.204s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities

[malex@thermalite mongodb-atlas-client]$ vi connection.js

[malex@thermalite mongodb-atlas-client]$ cat connection.js

const { MongoClient } = require('mongodb');

async function main() {
    /**
     * Connection URI. Update , , and to reflect your cluster.
     * See https://docs.mongodb.com/ecosystem/drivers/node/ for more details
     */
    const uri = "mongodb+srv://node_user:pass123@cluster101.n7nqjv.mongodb.net/test?retryWrites=true&w=majority";


    /**
     * The Mongo Client you will use to interact with your database
     * See https://mongodb.github.io/node-mongodb-native/3.3/api/MongoClient.html for more details
     */
    const client = new MongoClient(uri);

    try {
        // Connect to the MongoDB cluster
        await client.connect();

        // Make the appropriate DB calls
        await listDatabases(client);

    } catch (e) {
        console.error(e);
    } finally {
        // Close the connection to the MongoDB cluster
        await client.close();
    }
}

main().catch(console.error);

/**
 * Print the names of all available databases
 * @param {MongoClient} client A MongoClient that is connected to a cluster
 */
async function listDatabases(client) {
    databasesList = await client.db().admin().listDatabases();

    console.log("Databases:");
    databasesList.databases.forEach(db => console.log(` - ${db.name}`));
};


[malex@thermalite mongodb-atlas-client]$ node connection
(node:351200) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
Databases:
 - sample_airbnb
 - sample_analytics
 - sample_geospatial
 - sample_mflix
 - sample_restaurants
 - sample_supplies
 - sample_training
 - sample_weatherdata
 - admin
 - local
[malex@thermalite mongodb-atlas-client]$