Multiple database switching dynamic in node-express - javascript

i have searched lot to get a solution to my problem. but didn't got it.
if anyone have the experience in such situations please help me.
i have created a application server in node express with MySQL a database.
and successfully create REST API endpoints which works successfully.
but our projects scaled up. a new client approaches so we need to serve those clients too.
those client may have 1k users.but the database schema is same.
solution 1: create a separate server and database for each client with different port no.
but i don't think this is good solution because if we have 100 client we can't maintain the code base.
solution 2: create a separate database for each client and switch database connection at run time.
but i don't understand how to implement solution 2. any suggestion highly appreciated.
if more than one client requesting same server how to know which database need to connect using the endpoint URL. i there any alternate way to tackle this situation.
my solution: create a middle ware to find out the which database is required and return the connection string.is it good idea.             
middleware. in below example i use JWT token which contain database name.
const dbHelper=new db();
class DbChooser {
constructor(){
this. db=
{
wesa:{
host: "xxx",
user: "xxxx",
password: "xxxxx",
database: "hdgh",
connectionLimit:10,
connectTimeout:30000,
multipleStatements:true,
charset:"utf8mb4"
},
svn:{
host: "x.x.x.x.",
user: "xxxx",
password: "xxx",
database: "xxx",
connectionLimit:10,
connectTimeout:30000,
multipleStatements:true,
charset:"utf8mb4"
}
};
}
async getConnectiontring(req,res,next){
//console.log(req.decoded);
let d=new DbChooser();
let con=d.db[req.decoded.userId];
console.log(mysql.createPool(con));
next();
}
}
module.exports=DbChooser;

You can create a config JSON. On every request, request header should have a client_id based on the client_id we can get the instance of the database connection.
your db config JSON
var dbconfig = {
'client1': {
databasename: '',
host: '',
password: '',
username: ''
},
'client2': {
databasename: '',
host: '',
password: '',
username: ''
}
}
You should declare a global object, to maintain the singleton db instances for every client.
global.dbinstances = {};
on every request, you are going to check whether the instance is already available in your global object or not. If it's available you can go continue to the next process, otherwise it creates a new instance.
app.use('*', function(req,res) {
let client_id = req.headers.client_id;
if(global.instance[client_id]) {
next();
} else {
const config = dbconfig[client_id];
connectoDb(config, client_id);
}
}
function connectoDb(config, client_id) {
//.. once it is connected
global.instance.push({client_id: con}); //con refers to the db connection instance.
}

Related

How do i send the data in my javascript query to mysql database by a push of a button?

I'm very new to databases and mysql, but i have to know how i update my database from a pre-written javascript query. Until now i have done it manually over the terminal in javascript with: node main.js. This works just fine but i want to do this with a button.
const { createPool } = require('mysql')
const pool = createPool({
host: 'localhost',
user: 'root',
password: '',
connectionLimit: 10,
})
pool.query(`
insert into test.users(first_name, last_name, email)
values('${fname.value}', '${lname.value}', '${email.value}')
`)
Thank you in advance.
I could not try very much because i didn't find much and all the tutorials i watched on youtube were not helpful at all.

Share Oracle database connection in NodeJS for MVC architecture

I'm quite new with the implementation of Oracle database with Node.js, currently I'm using oracledb library to connect my Node.js app to my Oracle database as follows
connection = await oracledb.getConnection({
user: "SYS",
password: password,
connectString: "localhost:1522/userdb",
privilege: oracledb.SYSDBA
});
I set everything up as a monolithic app(It's a simple user review app) to start, but I want to split the code in User and Review Controller, the same for the service, model for both objects.
The only problem I have now (That I know of), is that I am not able to make each model (User and Review) to take that connection and simply send a query depending on what the controller needs. I tried to create a separate db.js file and set the connection there and then use
class DBConnection {
constructor() {
this._connect();
}
async _connect() {
try {
connection = await oracledb.getConnection({
user: "SYS",
password: password,
connectString:process.env.DATABASE,
privilege: oracledb.SYSDBA
});
} catch (err) {
console.log(err.message);
}
}
}
module.exports = new DBConnection();
Then I would try to import it and use something like:
connection= DBConnection();
connection.execute(query);
But it has not worked, is there any way to do this?

How to Using Nodemailer

I want to ask how to using nodemailer with dynamic email and pass from database
export const mailTransporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: email_user,
pass: email_pass,
},
});
email_user and email_pass from file env, I want to email_user and email_pass from the database, so I think to create a function for getting value email and pass from the database, then save into variable and use in mailTransport. Guys any suggestion or opinion for it?
Wrap your nodemailer.createTransport into a function before you export it, then from the function, you get the credential from DB before constructing the nodemailer.createTransport.
module.exports = createTransportWithCredential
function createTransportWithCredential(){
return new Promise((resolve,reject)=>{
//get credential from DB, you may need to use promise-then to handle async situation
//example:
getCredentialFromDB().then(credentials=>{
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: credential.user,
pass: credential.password,
},
});
resolve(transporter)
})
})
}
From the other js file you can do:
const mailer = require("./nodemailer")
mailer.createTransportWithCredential().then(transporter=>{
//use the transporter
})
Depends on what type of database you have. If you're using mysql you can use the mysql2 package to make queries. It looks like this.
I recommend creating a simple package outside of your main project but this is not completely necessary.
npm init
npm install dotenv mysql2
require('dotenv').config({ path: "/home/ubuntu/.env" });
const mysql = require("mysql2/promise");
const connection = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: "main",
flags: "-FOUND_ROWS",
charset: "utf8mb4_0900_ai_ci",
multipleStatements: true,
connectionLimit: 10,
queueLimit: 0
});
module.exports = connection;
Edit the options as you like. This one creates a pool of 10 connections and connects to a database named main. It also allows for multiple statements within a single query. That might not be desirable so turn that off if you'd like. Finally, I'm requiring an environment file, but I am specifying a specific location rather than getting one automatically from within the project folder (since this is its own package that will be imported into the main project).
Next we import the database package into our main project.
Just follow this page to install a local package Installing a local module using npm?
It should be something like this while inside your main project directory.
npm install ../database
if your database package is located next to your main project folder. Just replace ../database with whatever the path is to the separate database package.
Now inside our main project, it would look something like this. (I'm assuming you labelled your new package database but if not, just replace with whatever name you used.
require('dotenv').config({ path: "/home/ubuntu/.env" });
const connection = require("database");
const userID = "81cae194-52bd-42d3-9554-66385030c35b";
connection.query(`
SELECT
EmailUsername,
EmailPassword
FROM
UserEmail
WHERE
UserID = ?
`, [userID])
.then(([results, fields]) => {
let transporter = nodemailer.createTransport({
host: process.env.EMAIL_HOST,
port: process.env.EMAIL_PORT,
secure: true,
auth: {
user: results[0].EmailUsername,
pass: results[0].EmailPassword
},
});
// Put transporter.sendMail() here
})
.catch(error => console.log(error));
This is just a sample of what you could do and how you could do it. You need to use your own critical thinking to fit it into your own project and style.
There is no one way to do it and some of the choices I've made are personal decisions. You should be able to merge this with Jerry's answer. He goes more into how to create the nodemailer module. I am only showing you how to connect database data with nodemailer.
Please read up on https://www.npmjs.com/package/mysql2 especially the promise wrapper section. This solution also uses dotenv https://www.npmjs.com/package/dotenv and https://nodemailer.com/about/

Sending data to Database in React.js web application

I'm creating a web application and I'm curious how to send data to MySQL database in it. I have a function that is invoked when user presses button, I want this function somehow to send data to the MySQL server. Does anyone know how to approach this problem? I tried npm MySQL module but it seems the connection doesn't work as it is client side. Is there any other way of doing it? I need an idea to get me started.
Regards
You will need a server that handles requests from your React app and updates the database accordingly. One way would be to use NodeJS, Express and node-mysql as a server:
var mysql = require('mysql');
var express = require('express');
var app = express();
// Set up connection to database.
var connection = mysql.createConnection({
host: 'localhost',
user: 'me',
password: 'secret',
database: 'my_db',
});
// Connect to database.
// connection.connect();
// Listen to POST requests to /users.
app.post('/users', function(req, res) {
// Get sent data.
var user = req.body;
// Do a MySQL query.
var query = connection.query('INSERT INTO users SET ?', user, function(err, result) {
// Neat!
});
res.end('Success');
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
});
Then you can use fetch within a React component to do a POST request to the server, somewhat like this:
class Example extends React.Component {
constructor() {
super();
this.state = { user: {} };
this.onSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
var self = this;
// On submit of the form, send a POST request with the data to the server.
fetch('/users', {
method: 'POST',
data: {
name: self.refs.name,
job: self.refs.job
}
})
.then(function(response) {
return response.json()
}).then(function(body) {
console.log(body);
});
}
render() {
return (
<form onSubmit={this.onSubmit}>
<input type="text" placeholder="Name" ref="name"/>
<input type="text" placeholder="Job" ref="job"/>
<input type="submit" />
</form>
);
}
}
Keep in mind that this is only one of infinite ways to achieve this.
It depends on how your application is organized, I will guess that you have a server that provides your React application code.
I would advise you to send the necessary information to your server (if there is any) using a module based on your preferences:
fetch built-in XHR api (https://developer.mozilla.org/en/docs/Web/API/Fetch_API)
request callback-based npm module (https://www.npmjs.com/package/request)
axios promise-based npm module (https://www.npmjs.com/package/axios)
If you are looking for a module/plugin doing all the work from client to database I don't know any and not sure there is because it is usually advised to use a proxy (a server to redirect but also to format or block requests between your client and the database).
Then, in your server you format the necessary information (if any) to be usable by your MySQL database, and then contact your MySQL database with the module of your choice, the first most popular module seems to be:
https://www.npmjs.com/package/mysql, but if you know another one or have other preferences go on. (For example with MongoDB we can use Mongoose to make requests easier)

Send data back to node.js server from front-end

I am new to Node.js and I'm trying to figure out for few days how to make a simple login-register feature for a website using Express.js with EJS template engine and MySql.
I have installed Node on my PC and I've used the Express-Generator to make a basic folder structure (views, routes, public folders).
I understand how I can pass variables from node to the front end using ejs but I don't know how to pass it back. I've tried watching some tutorials on the internet but nothing seems to make me see the logic. Where do I put the MySql code? How can I pass back the input values once the user clicks "SUBMIT"?
How says Jake, I suggest to use Sequelize for MySQL.
I will try to make a small steps for your start, and after you can study more about each process and tool.
1) Front-end (EJS);
<form id="login" action="/login" method="post">
<input name="username" type="text">
<input name="password" type="password">
<input type="submit">Ok</input>
</form>
Here, the form will request the route login. The route:
2) Route
module.exports = function (app){
var login = app.controllers.login;
app.get('/', login.index);
app.post('/login', login.login)
};
The route will call the login method in the controller called login.js.
3) Controller
module.exports = function(app) {
var sequelize = require('./../libs/pg_db_connect'); // resquest lib of connection to mysql/postgres
var LoginController = {
index: function(req, res) {
res.render('login/index');
},
login: function(req, res) {
var query = "SELECT * FROM users"; // query for valid login
sequelize.query(query, { type: sequelize.QueryTypes.SELECT}).then(function(user){
if (req.body.username == user[0].username && req.body.password === user[0].password ){
res.redirect("/home");
} else {
res.render("login/invalid_access");
}
});
}
};
return LoginController;
};
In this point, is exec the query for to valid the login and verify if user can be log in. Request method is the main point.
For response and send information to view, it used res.SOME_METHOD:
res.send();
res.end();
res.download();
res.json();
Plus: Sequelize MySQL connection.
In the express structure, it's localized in lib/my_db_connection.js:
var Sequelize = require('sequelize');
module.exports = new Sequelize('database_name', 'user', 'pass', {
host: 'localhost',
dialect: 'mysql',
pool: {
max: 10,
min: 0,
idle: 10000
},
});
I suggest before you code, read the necessary docs.
You're going to have to use some sort of AJAX library (or vanilla js ajax) to send the information to a http endpoint you set up in express. For simple stuff the jquery ajax methods will do just fine. You will likely are looking to make a POST request.
As for the MySql code, checkout Sequelize. Its a cool library for interacting with sql databases from express. Its similar to how mongoose works for mongo.

Categories

Resources