Setting Up a Node.js Application in Reclaim Cloud (1)

There's a resource here https://www.virtuozzo.com/application-platform-docs/nodejs-center/ but I found it so high-level it wasn't really useful. This is a practical step-by-step approach.

1. Create a new environment in reclaim cloud

Resource: https://support.reclaimhosting.com/hc/en-us/articles/4404919752215-Creating-New-Environments-in-Reclaim-Cloud 

I selected node.js as my application and Maria DB as my MySQL database. 

2. Set up an end point for the node.js application

    - click on 'Settings' for the environment

   - select 'End Points' from the menu to the left

  - Click 'Add'

  - Enter any name you want, and '3000' for the port (note: this port number is defined in index.js, below).

  - Click 'Add'. The system will select it's own 'public port', which is what you actually use to access the application. In my case, the end point was:

   http://node11977-env-3877043.ca.reclaim.cloud:11008

In other words, it replaced port '3000' with port '11008'.

3. Generate an SSH Key Pair

Resource: https://support.reclaimhosting.com/hc/en-us/articles/8421003621015-Generating-and-using-SSH-key-pairs#generating-and-using-ssh-key-pairs-0-0 

The public key is like a lock.

The private key is the key that opens the lock. Never share it.

Download PuTTY gen Portable Executable to create the keys (for Windows): https://winscp.net/eng/downloads.php#putty_additional 

Alternatively, In Mac, Linux or Windows Subsystem for Linux (WSL), to generate the keys use the following command:

 ssh-keygen -t ed25519

If you decide to use WSL to generate the keys, find them using Explorer in Windows. Type the following in the address bar: 

\\wsl$

and press enter. Resource: https://www.howtogeek.com/426749/how-to-access-your-linux-wsl-files-in-windows-10/ 

4. Access the node.js environment using SFTP

Resource: https://www.exavault.com/blog/import-ssh-keys-winscp

I use Win-SCP for FTP access

To load private key: 

   - select 'session' then 'new session'

   - click on 'advanced'

   - click on SSH: Authentication

   - select 'private key file' (click on three dots to the right)

   - select the private key created in the previous step

   - click OK

To find the STFP address to load:

   - go to the Reclaim Cloud environment and highlight the node.js server, then select 'settings' (the gear icon) and pick SFTP/Direct SSH Access

   - get the address from the display

   - enter that into the address field for WinSCP

and you should see the contents of the node.js server in the right hand window.

Some things to note:

The directory ROOT is the default node.js application created by the platform, but we don't need to use this (some guides recommend deleting it entirely).

5. Set up the database

- Go to phpMyAdmin in the cloud environment (the address will be in the email Reclaim sent you titled 'MariaDB Node Added to Your Reclaim Cloud Environment').

- Create a new database (which I called NodeMySQL) and then add tables (I'm using the tables suggested here: https://blog.logrocket.com/build-rest-api-node-express-mysql/  ). For example, paste and run the following commands in the SQL form:

CREATE TABLE `programming_languages`
(
  `id`            INT(11) NOT NULL auto_increment ,
  `name`          VARCHAR(255) NOT NULL ,
  `released_year` INT NOT NULL ,
  `githut_rank`   INT NULL ,
  `pypl_rank`     INT NULL ,
  `tiobe_rank`    INT NULL ,
  `created_at`    DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  `updated_at`    DATETIME on UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  PRIMARY KEY (`id`),
  UNIQUE `idx_name_unique` (`name`(255))
)
engine = innodb charset=utf8mb4 COLLATE utf8mb4_general_ci;
INSERT INTO programming_languages(id,name,released_year,githut_rank,pypl_rank,tiobe_rank) 
VALUES 
(1,'JavaScript',1995,1,3,7),
(2,'Python',1991,2,1,3),
(3,'Java',1995,3,2,2),
(4,'TypeScript',2012,7,10,42),
(5,'C#',2000,9,4,5),
(6,'PHP',1995,8,6,8),
(7,'C++',1985,5,5,4),
(8,'C',1972,10,5,1),
(9,'Ruby',1995,6,15,15),
(10,'R',1993,33,7,9),
(11,'Objective-C',1984,18,8,18),
(12,'Swift',2015,16,9,13),
(13,'Kotlin',2011,15,12,40),
(14,'Go',2009,4,13,14),
(15,'Rust',2010,14,16,26),
(16,'Scala',2004,11,17,34); 

Here's what it looks like in phpMyAdmin:


 Click 'Go' to submit the command.

6. Set up our node.js application 

I'm installing Express.js

- Open an SSH window into the node.js application

- in the SSH window, make a directory for the application and cd into it:

mkdir programming-languages-api && cd programming-languages-api

- install the application dependencies using npm

npm i express

  

 - install the node mysql2 module, which is needed by the application below

npm i mysql2

 - using a text editor (I use Visual Studio Code) in a clean directory, create an index.js file. I used the one recommended here: https://blog.logrocket.com/build-rest-api-node-express-mysql/ 

- using WinSCP (or your sftp client) upload index.js to the application directory (in this case, 'programming-languages-api').

- Start the node server in the SSH window:

node index.js

You should now see the 'ok' result in your browser at the end-point. Note that the end point is not localhost:3000 like it says in the article; it's the end point we defined in step 2. In my case, I accessed it using:

 
You can stop the server to continue working using the ctl/C command in the SSH window

7. Set up the node REST environment

- create 'routes' and 'services' directory under the programming-languages-api directory

- create a config.js file for the database. The configuration information is found in the email from Reclaim titled 'MariaDB Node Added to Your Reclaim Cloud Environment'. Here's mine:

   const config = {
    db: {
      /* don't expose password or any sensitive info, done only for demo */
      host: "node11976-env-3877043.ca.reclaim.cloud",
      user: "root",
      password: "MVKvlz13312",
      database: "NodeMSQL",
    },
    listPerPage: 10,
  };
  module.exports = config;

I also created other application finds, including helper.js, etc. from the instructions at https://blog.logrocket.com/build-rest-api-node-express-mysql/ 

These are straight from the LogRocket article (I'm including them in case the original article ever disappears):

helper.js

function getOffset(currentPage = 1, listPerPage) {
  return (currentPage - 1) * [listPerPage];
}

function emptyOrRows(rows) {
  if (!rows) {
    return [];
  }
  return rows;
}

module.exports = {
  getOffset,
  emptyOrRows
}

services/db.js   

(connects to the server to execute the request)

const mysql = require('mysql2/promise');
const config = require('../config');

async function query(sql, params) {
  const connection = await mysql.createConnection(config.db);
  const [results, ] = await connection.execute(sql, params);

  return results;
}

module.exports = {
  query
}

services/programmingLanguages.js  

(connects the request to the db function - note that in the orighinal article there is an error in the name of this function).

const db = require('./db');
const helper = require('../helper');
const config = require('../config');

async function getMultiple(page = 1){
  const offset = helper.getOffset(page, config.listPerPage);
  const rows = await db.query(
    `SELECT id, name, released_year, githut_rank, pypl_rank, tiobe_rank 
    FROM programming_languages LIMIT ${offset},${config.listPerPage}`
  );
  const data = helper.emptyOrRows(rows);
  const meta = {page};

  return {
    data,
    meta
  }
}

module.exports = {
  getMultiple
}

routes/programmingLanguages.js

(connects the request to the function)

const express = require('express');
const router = express.Router();
const programmingLanguages = require('../services/programmingLanguages');

/* GET programming languages. */
router.get('/', async function(req, res, next) {
  try {
    res.json(await programmingLanguages.getMultiple(req.query.page));
  } catch (err) {
    console.error(`Error while getting programming languages `, err.message);
    next(err);
  }
});

module.exports = router

index.js

(This is a rewritten version of the index.js file from above, and handles the incoming 'programming-languages' request)

const express = require("express");
const app = express();
const port = 3000;
const programmingLanguagesRouter = require("./routes/programmingLanguages");
app.use(express.json());
app.use(
  express.urlencoded({
    extended: true,
  })
);
app.get("/", (req, res) => {
  res.json({ message: "ok" });
});
app.use("/programming-languages", programmingLanguagesRouter);
/* Error handler middleware */
app.use((err, req, res, next) => {
  const statusCode = err.statusCode || 500;
  console.error(err.message, err.stack);
  res.status(statusCode).json({ message: err.message });
  return;
});
app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
}); 

This code now allows us to read the content from the database.

If the server is still running, stop it with ctl/C

Then start it again in the SSH window:

node index.js

Access the database with the 'programming-languages' command:


OK, that's it for now. More to come.
 
Here's the video of today's work, which is probably excruciatingly boring for most everyone: youtube.com/watch?v=3w7jP4O-Uh

I still need to do the C,U and D parts of my CRUD application, and also to figure out how to make it work as an https. But I'm pretty happy with where I ended up today.

 

 

 







Comments

Popular Posts