I have the following in my app.js file:
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'localhost',
port: 3306,
user: 'user',
password: 'password',
database: 'mydatabase'
});
connection.connect();
In routes/index.js, I currently have only the boilerplate code:
var express = require('express');
var router = express.Router();
module.exports = router;
How do I make available the connection object from the app.js file in routes/index.js?
I ended up splitting the database connection logic from the app.js file. In a separate file called connection.js, I have the following:
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'localhost',
port: 3306,
user: 'user',
password: 'password',
database: 'mydatabase'
});
module.exports = connection;
Then in my route file, I add
var connection = require('../connection');
to the top of the file where all my other modules are brought in. In my instance, the connection.js file is one level higher than my route file, hence the ../ in the require() function parameter.
My preference is to do some simple dependency injection and pass the required resource into the router by wrapping the module in a function:
var express = require('express');
module.exports = function (connection) {
var router = express.Router();
//do stuff with the connection
return router;
}
Then you just instantiate the router module in app.js as a function with the database connection as an argument:
app.use('/where/ever', require('./module-b')(connection));
Usually I wrap up the dependencies in an object:
app.use('/where/ever', require('./module-b')({db:connection}));
This way you don't have to keep changing the function signature as dependencies are added. This gives you a super-lightweight inversion of control container for your express applications.
I had the same problem, and Lloyds' suggestion was kind of a solution for me but I just didn't want to be stuck on a single type of db, I want to be able to move my app to another db with just a new implementation of a single class.
So that worked for me:
function DataAccess(connectionData) {
//Using the connectionData...
}
var _dataAccessInstance;
module.exports = function (connectionData) {
if (!_dataAccessInstance) {
_dataAccessInstance = new DataAccess(connectionData)
}
return _dataAccessInstance;
};
And then the usage will be just require the file:
//The object is the connection data to be sent to the module
var dataAccess = require('./data-access')({});
Sure, this has its own flaws like every module must know and send the connection data. But I assume the data is stored in the configuration and all hte modules can access it.
Check out express-myconnection, it lets you access the MySQL
connection from within your routes.
Update: After using express-myconnection in production, I would not recommend it - it leaks connections, causing requests to hang (callback will never be called), and it is no longer actively maintained.
Related
I am creating a application that will communicate over Udp protocol in node js. Also i am using sql server as a database so in order to connect this database i am using mssql npm liabrary. Basically what i am doing i have one separate module for dbcon as shown below
const sql = require('mssql')
const config = {
user: 'sa',
password: '123',
server: '192.168.1.164', // You can use 'localhost\\instance' to connect to named instance
database: 'SBM-EMCURE',
options: {
encrypt: false // Use this if you're on Windows Azure
}
}
sql.connect(config, err => {
})
sql.on('error', err => {
console.log('error on sql.on()');
})
module.exports.sql = sql;
And i am using this exported sql object to run my queries outside dbcon module but it gives me different behavior sometimes like query executes before databse connection, is there is any way to use single database connection for entire application?. Using single database connection is useful or it will slow down my process
Thanks in advance
You could:
Pass the instance into each router and use it there when you set them up
Set the instance as a property of your app object and access it from req.app.sql or res.app.sql within your middleware functions
Set the instance as a property of the global object and access it from anywhere (typically not a best practice though)
Also, in your example code, you're initiating the connection by calling sql.connect(), but you don't give it a callback for when it's finished connecting. This is causing it to be immediately exported and probably queried before the connection is actually established. Do this:
const util = require('util');
const sql = require('mssql');
const config = {
user: 'sa',
password: '123',
server: '192.168.1.164',
database: 'SBM-EMCURE',
options: {
encrypt: false
}
};
module.exports = util.promisify(sql.connect)(config);
Then you can retrieve the instance with:
const sql = await require('./database.js');
first you should create file database.js:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '127.0.0.1',
user : 'root',
password : '',
database : 'event'
});
connection.connect(function(err) {
if (err) throw err;
});
module.exports = connection;
Then you can use this connection in server.js or any other file.
var express = require('express');
var app = express();
var dbcon = require('./database');
app.get('/getEvent',function(req,res){
dbcon.query('SELECT * FROM eventinfo',function(err, result) {
if (err) throw err;
});
});
app.listen(3000);
What does createConnection do?
var connection = mysql.createConnection({
host : 'example.org',
user : 'bob',
password : 'secret'
});
I'm writing an application in nodeJS using mysql module. I have some own modules, for example authentication, which definetely needs DB connection. Question is: if I have multiple modules where I use this method to create the connection, will it create a new connection for me everytime or use the first one? If creates, it creates the first time it loads my own module or everytime? Oh, and if it creates when is it going to be destroyed?
Here's how I have it in my authentication module:
var config = require('./config.js');
var mysql = require('mysql');
var connection = mysql.createConnection(config.connectionString);
exports.login = function() ...
I have some basic understanding missings about how modules and own modules work.
Thanks for the answers.
You can create a connection pool in one module and then share that pool across all your modules, calling pool.getConnection() whenever you need to. That might be better than keeping a single, shared connection open all the time.
One project I'm working on does this:
utils/database.js
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit: 100,
host: 'localhost',
user: 'xxxxx',
password: 'yyyyy',
database: 'zzzzz',
debug: false
});
module.exports = pool
accounts.js
var express = require('express');
var router = express.Router();
var pool = require('./utils/database');
router.get('/', function(req, res) {
pool.getConnection(function(err, connection) {
// do whatever you want with your connection here
connection.release();
});
});
module.exports = router;
Another way I'm playing around with is like this:
utils/database.js
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit: 100,
host: 'localhost',
user: 'xxxxx',
password: 'yyyyy',
database: 'zzzzz',
debug: false
});
var getConnection = function(callback) {
pool.getConnection(function(err, connection) {
callback(err, connection);
});
});
module.exports = getConnection;
accounts.js
var express = require('express');
var router = express.Router();
var createConnection = require('./utils/database');
router.get('/', function(req, res) {
createConnection(function(err, connection) {
// do whatever you want with your connection here
connection.release();
});
});
module.exports = router;
It will create a new connection every time you call connection.connect().
The connection is destroyed when either the program exits, or connection.end() is called. If you want to reuse the connection, you can put the connection logic in a separate module and then just export the connection itself, like this.
In a file called connection.js
var mysql = require("mysql");
var connection = mysql.createConnection({
host : 'localhost',
user : 'user',
password : 'password'
});
connection.connect();
module.exports = connection;
And then in any client file:
var connection = require("./connection.js");
connection.query('some query', callback);
Each file the requires connection.js will reuse the existing connection.
The question is about architecture.
I got a module 'db', which establishes connection to mongodb and has a class with schemas, models etc. I export exemplar of that class.
Should i just require('db') in every route file or just do this in one:
server.on('request', function(req) {
req.db = db;
});
db.js:
"use strict";
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var conn = mongoose.connection;
conn.on('error', console.error.bind(console, 'connection error:'));
conn.once('open', function() {
console.log("Connected to MongoDB.");
});
class db {
constructor() {
//Users
this._usersSchema = mongoose.Schema(
{
username: String,
password: String,
email: String
});
this.Users = mongoose.model("Users", this._usersSchema);
}
}
module.exports = new db();
I think you will find differing opinions, but I prefer to require wherever I need it. modules in node are singletons, so you are always getting the same instance. And I like to separate out my controller logic into their own files away from the routes. Moreover the logic does not expect the complete request and response objects. The reason is I can then use the same code to grab data necessary to serve an API endpoint or render the view server-side without having the mock an entire request and response object.
I'm trying to set up this simnple NodeJS/mongodb app and I have my files structured like this:
server.js
|
+-routes/menu.js
+-routes/cases.js
In my server.js I declare my mongodb vars like this:
var express = require('express'),
mongo = require('mongodb'),
Server = mongo.Server,
MongoClient = mongo.MongoClient,
Db = mongo.Db,
http = require('http'),
app = express(),
httpServer = http.createServer(app),
bodyParser = require('body-parser'),
server = new Server('host.mongohq.com', 10066, {auto_reconnect : true}),
db = new Db('myDb', server);
db.open(function(err, client) {
client.authenticate('myUser', 'myPassword', function(err, success) {
console.log('Authenticated');
});
});
var cases = require('./routes/cases'),
menu = require('./routes/menu');
But then when I try to reference my db var in eg menu.js like this:
db.collection(myCollection, function(err, collection) {});
I get an error that db is not defined.
Obviously I can move all the mongodb declarations down to both my menu.js and cases.js file but that's just very elegant. So how do I create one mongodb instance var and refer to it from my included files?
Thanks in advance...
You need to require server.js in your menu.js file.
Your db object isn't global. If you want it to be, declare it without var.
I'm completely new to nodejs + expressjs comming from php and I'm getting trouble how to export/include a var to my routes/users.js file.
on app.js I have:
//database connection
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'dbNodeExpress'
});
... some code
var user = require('./routes/user'); //here I include my routes/files (I dont know if it's right to include the routes here - for learning purposes it works for now)
... more code until starts the server
On my /routes/user.js
app = require('../app');
//var mysql = require('mysql');
var baseUrl = app.get('baseUrl');
app.get('/users_mysql', function(req, res){
connection.query('SELECT * FROM users', function(err, users){
res.json(users);
});
});
and I get the express error: 500 ReferenceError: connection is not defined
The connection works because if I move the content from users.js to app.js I can query the database.
My questions is how to inject the var connection to be used on routes/users.js
Any help / hint to understand this is very appreciated. Thanks in advance.
There are several ways you could do this. A couple solutions might be:
Create a resources.js file that creates and exports the connection. Then require() resources.js in every source file where you need it.
Pass the connection to your user route file. Something like this:
// app.js
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'dbNodeExpress'
});
require('./routes/user')(connection);
// routes/user.js
module.exports = function(connection) {
app.get('/users_mysql', function(req, res){
connection.query('SELECT * FROM users', function(err, users){
res.json(users);
});
});
};
create a database connector javascript file. as like database_connector.js
and require it when ever you want to have the connection pooled or the connection class availabel to your models. tip : you can also export config files like below or use barely values.
var mysql = require('mysql');
var config = require("./config");
function Connection() {
this.pool = null;
this.init = function() {
this.pool = mysql.createPool({
connectionLimit: config.poolSize,
host: config.host,
user: config.user,
password: config.password,
database: config.database,
debug:config.debug,
});
};
this.acquire = function(callback) {
this.pool.getConnection(function(err, connection) {
callback(err, connection);
});
};
console.log("connection"+this.pool);
}
module.exports = new Connection();