This question already has answers here:
Best way to share database connection param with mongoose/node.js
(3 answers)
Closed 8 years ago.
I've created an extremely simple Node.js app based on Express's route-separation example. I want to power this app with the MongoDB driver Mongoose. This example just lists Users and Kittens.
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var user = require('./user');
var kitten = require('./kitten');
// Connect MongoDB
mongoose.connect('mongodb://localhost/mongoose');
// Express config here
...
// User
app.all('/users', user.list);
// Kitten
app.all('/kittens', kitten.list);
// Mongoose connection
var db = mongoose.connection;
db.once('open', function callback () {
var kittySchema = mongoose.Schema({ name: String });
});
if (!module.parent) {
app.listen(3000);
console.log('Express started on port 3000');
}
To me it seems it would be wise to connect to the Mongo database on startup rather than for each request.
But how do I share that Mongoose connection with both the user and kitten routes? I know if I didn't need to share the connection between the two, I could just connect to the database in my user.js and kitten.js code.
In node.js when you do require a file, you run the code in that file exactly once. Which means you can store things through closure.
foobardb.js
(function(){
"use strict"; // always nice to have
var mongoose = require('mongoose'),
databaseConnection;
module.exports = function() {
if ( !databaseConnection ) {
mongoose.connect('mongodb://localhost/mongoose')
databaseConnection = mongoose.connection;
}
(...)
};
})();
The databaseConnection will be shared with all the require("foobardb.js"); you do
Related
I am writing a RESTful API. IT runs on node.js using the express.js framework, mongodb using mongoose as the object modelling tool & body-parser to pass the http. Everytime I start the server & navigate to the specified IP address, I get a "CANNOT GET/" error. How can I can around this? Some advice would be much appreciated .
I have tired using a different port number but the problem still persists.
Here is a copy of my server.js code:
var express = require('express'),
app = express(),
IP = process.env.IP,
port = process.env.PORT || 8080 ,
mongoose = require('mongoose'),
tasks = require('./api/models/todosModel'),
bodyParser = require('body-parser');
//handiling of promise
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/Todosdb',{ useNewUrlParser: true });
app.use(bodyParser.urlencoded({extended:true})); // telling the sever instance to use body parser
app.use(bodyParser.json());
var Routes = require('./api/routes/todoRoutes');
//passing the server instance to the routes
Routes(app);
app.listen(port,IP);
console.log("The TODO API server is running on IP: " + IP + " and port: " + port);
The todoRoute code :
'use strict';
module.exports = function(app){
var todofunctions = require('../controllers/todoController');
// todo routes
app.route('/tasks') //task [GET (all the tasks),POST]
.get(todofunctions.listTasks)
.post(todofunctions.createTask);
app.route('/tasks/:taskId') //a task [GET(single task),PUT,DELETE]
.put(todofunctions.updatetask)
.get(todofunctions.readTask)
.delete(todofunctions.deleteTask);
};
It's probably because you have not defined any handler for /.
Try going to the /tasks instead in your browser, then you will get some response.
I am new to creating nodejs application. I am trying to get started with simple angular, and nodejs application. I have saved my data in "mLab". Now when I am trying to display my data through this below code, my nodemon server is crashing describing,
"MongoError: failed to connect to server [ds030817.mlab.com:30817]".
Here is my code I have copied from other source.
var express = require('express');
var router = express.Router();
var mongojs = require('mongojs');
var db = mongojs('mongodb://<dbuser>
<dbpassword>#ds030817.mlab.com:30817/user_data_0001',['books']);
router.get('/tasks', function(req, res, next){
db.books.find(function(err, books){
if(err){
res.send(err);
}
res.json(books);
})
});
module.exports = router;
Your connection string format is not right. Use following
var db = mongojs('mongodb://dbuser:dbpassword#ds030817.mlab.com:30817/user_data_0001',['books']);
I'm developing my first Node.js App with Socket.IO and everything is fine but now the app is slowly getting bigger and I'd like to divide the app-code into different files for better maintenance.
For example I'm defining all my mongoose schemas and the routings in the main file. Underneath are all the functions for the socket.IO connection. But now I want to have an extra file for the schemas, an extra file for routing and one for the functions.
Of course, I'm aware of the possibility to write my own module or load a file with require. That just does not make sense for me, because I can't work with the vars like app, io or db without making them global. And if I pass them to a function in my module, I can't change them. What am I missing? I'd like to see an example how this is done in practice without using global vars..
It sounds like you have a highly coupled application; it's difficult for you to split out your code into modules because pieces of the application that should not depend on each other do. Looking into the principles of OO design may help out here.
For example, if you were to split your dataabse logic out of the main application, you should be able to do so, as the database logic should not depend on app or io--it should be able to work on its own, and you require it into other pieces of your application to use it.
Here's a fairly basic example--it's more pseudocode than actual code, as the point is to demonstrate modularity by example, not to write a working application. It's also only one of many, many ways you may decide to structure your application.
// =============================
// db.js
var mongoose = require('mongoose');
mongoose.connect(/* ... */);
module.exports = {
User: require('./models/user');
OtherModel: require('./models/other_model');
};
// =============================
// models/user.js (similar for models/other_model.js)
var mongoose = require('mongoose');
var User = new mongoose.Schema({ /* ... */ });
module.exports = mongoose.model('User', User);
// =============================
// routes.js
var db = require('./db');
var User = db.User;
var OtherModel = db.OtherModel;
// This module exports a function, which we call call with
// our Express application and Socket.IO server as arguments
// so that we can access them if we need them.
module.exports = function(app, io) {
app.get('/', function(req, res) {
// home page logic ...
});
app.post('/users/:id', function(req, res) {
User.create(/* ... */);
});
};
// =============================
// realtime.js
var db = require('./db');
var OtherModel = db.OtherModel;
module.exports = function(io) {
io.sockets.on('connection', function(socket) {
socket.on('someEvent', function() {
OtherModel.find(/* ... */);
});
});
};
// =============================
// application.js
var express = require('express');
var sio = require('socket.io');
var routes = require('./routes');
var realtime = require('./realtime');
var app = express();
var server = http.createServer(app);
var io = sio.listen(server);
// all your app.use() and app.configure() here...
// Load in the routes by calling the function we
// exported in routes.js
routes(app, io);
// Similarly with our realtime module.
realtime(io);
server.listen(8080);
This was all written off the top of my head with minimal checking of the documentation for various APIs, but I hope it plants the seeds of how you might go about extracting modules from your application.
I am working through a Mongo/Express tutorial and have run across a situation that I do not understand.
I have a MongoDB set up on my local machine.
I created a new database on my local called myapi use myapi
I added a collection db.something.insert({...})
I can view this data in the mongo command line db.something.find()
I created a very basic Express API. (code below)
Using mongoose I am (seemingly) able to connect to the database I just created. I can add, edit, delete, and read data using the API and Postman -- However, It seems to be a completely different database than the one I created on my local. I cannot fetch the data I added through the mongo command line in my API. And in command line, I cannot fetch data that I added using the Express API.
Can someone help explain what I am missing?
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var router = require('./routes/router.js');
// initialize api and configure to get data from POST
var api = express();
api.use(bodyParser.urlencoded({ extended: true }));
api.use(bodyParser.json());
var port = process.env.PORT || 3000;
// connect to DB
mongoose.connect('mongodb://127.0.0.1/myapi');
// register routes
api.use('/', router);
// start server
api.listen(port);
console.log('server started on port ' + port);
I'm trying to use Bookshelf along with Express 4.0 and can't seem to get them working together or rather, I can't seem to follow "best practices". The Bookshelf docs mention that one should always reuse the same instance of it throughout the app. It even lists an example:
// When the app starts
var app = express();
var knex = require('knex')(dbConfig);
var bookshelf = require('bookshelf')(knex);
app.set('bookshelf', bookshelf);
// elsewhere, to use the bookshelf client:
var bookshelf = app.get('bookshelf');
var Post = bookshelf.Model.extend({
// ...
});
However, I can't seem to get it working when I have to use app.get() in a separate file. For example, here's my app.js file (the root of my entire app):
var express = require('express');
var app = express();
var db = require('./server/db/db');
app.set('bookshelf', db);
var api = require('./server');
app.use(api);
Here's my db.js file that gets required above:
var express = require('express');
var app = express();
var knex = require('knex')({ //my db settings go here });
var bookshelf = require('bookshelf')(knex);
module.exports = bookshelf;
The above code works if I require it directly. Here's where the issue turns up. Whenever I want to actually use the bookshelf connection, no matter what file I'm in, I follow the same process but it fails and "bookshelf" is always undefined. Here's an example of an index.js file that's required and called "api" in the app.js:
var express = require('express');
var app = express();
var db = app.get('bookshelf');
console.log(db);
DB always comes up as undefined. Whenever I try to make a new Model, I use the same process except I do an db.Model.extend({}) and trying to access the Model property throws an error (because it's undefined).
From what I can use both Bookshelf and Express docs agree that this should work and it doesn't. Any ideas?
This line creates a new app every time you call it:
var myApp = express();
If you want to set or get variables from the same app, you'll have to pass it as an argument.
var api = require('./server')(myApp);
And then in your api module:
module.exports = function(app){
var db = app.get('bookshelf');
//....
};
On a side note: you don't have to worry about singletons in Node.js all you have to do is just require it.
var db = require('./path/to/db/config');
It'll only be instantiated once and cached for later calls.