How can two different Node.js servers communicate to one mongoose schema? - node.js

I have two servers (Public server and Admin Server) and I would like to access from both one mongoose schema. The main server is the Public one where everything happens, but sometimes, from Admin server I would like to access that schema. I could write the schema on both the servers, but that would mean bad code. If that is the only solution, I will do it. But, is there any other way of doing this? For MongoDB I have a third server, that is only for database. Could I write something there so that when I connect with mongoose to the MongoDB server to receive the model from there?
Let's say I have this code (somewhere, I don't know where yet).
const mongoose = require('mongoose');
const postSchema = mongoose.Schema({
title: {
type: String,
required: true,
}
});
const Post = new mongoose.model('Post', postSchema);
module.exports = Post;
What I am trying to do in a server file is for example to call Post.save() or whatever function I am trying to get, without having the schema on both servers.

I used Mongoose-Gen npm and created an API in order to get the schema from on server to another.

Related

how to use passport.js local strategy without creating a schema,or database model

I was trying to understand how to use the passport.js in Mongodb native driver,Express now the problem is that all the reference or tutorials are showing the LOCAL-STRATEGY by using mongoose which creates a schema or model........so now iam STUCK
Take a look at the mongodb documentation for their Nodejs driver.
mongoDB Node Driver
Sorry for being here for a little bit late, but maybe my answer would be helpful to others who seeking answer for this kind of question.
I assume that you were struggling with these problems:
How to reuse database connection among your project
You can define your MongoClient object once and reuse this across multiple modules in your project as follow:
dbUtil.js hold definition of MongoClient object:
const MongoClient = require('mongodb').MongoClient;
const SERVER_URI = // link to your server, for example: 'http://localhost:27017';
const DB_NAME = // database name, for example: 'test';
/* #WHY?:
(option 1?) : to let the server assign objectId instead of Node driver,
(option 2 & 3?) : to get rid of deprecation warnings
*/
const clientObj = new MongoClient(`${SERVER_URI}/${DB_NAME}`, {
forceServerObjectId: true,
useNewUrlParser: true,
useUnifiedTopology: true
});
module.exports = {
client: clientObj,
dbName: DB_NAME
}
In another module where you need to use the defined connection:
const { client, dbName } = require('dbUtil');
// Because client.connect() return a Promise, you should wrap everything
// inside an immediately-invoked expression like this
(async () => {
await client.connect(); // at first you need to open the connection client
const dbO = await client.db(dbName); // get the connection to database
/* perform database operations, for example:
dbO.collection(users).insertOne({ name:'mongoadmin' });
*/
client.close(); // remember to close the connection when you're done
})();
So instead of the Mongoose way of using User.find().exec(), in Mongo native driver you have to activate connection to Client first and then use client.dbO.collection('users') (which return a Promise).
What the heck is Passport and why it's needed for your project
Passport is authentication middleware for Express that support authentication from Facebook, Google, JWT,... and many other authentication strategies. It can be helpful when you need to you want to support authentication from multiple authentication portal. However, it's not a must-have.
Sometimes applying another layer of abstraction from third-party libraries not only bring no sense to you & your project, but also over-complicate your existed code base. You'd chose not to use Mongoose and adapted MongoDb native driver instead, stated that you didn't need schema & model stuffs. For the same logic, I don't see any necessity of adapting Passport. This link can be helpful to you in some way: another Stackoverflow post
To apply authentication using JSON web token to your Express routes, you need to do these following steps:
Generate token for user signed in
Verify token
Define protected routes and write middlewares for those
All these tasks can be done without any third-party modules/libraries!
I believe your question stems from using mongodb schema validation instead of mongoose schema. You can use another means of authentication like JWT which does not directly need models for its authentication.

Why do we import Mongoose in the Express server file?

I have a Node/Express app that uses Mongoose to talk to a MongoDB database. The Express server is configured in a file called server.js and the schema is in a separate models.js file. Following every project and tutorial I've seen so far, I have the mongoose.connect() configured in both places:
// server.js
const express = require('express');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const app = express();
mongoose.connect('mongodb://127.0.0.1/mydb');
// models.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const User = new Schema({
username: String,
password: { type: String, select: false },
name: String,
});
module.exports = mongoose.model('User', User);
My question is, since I'm already importing mongoose in models.js, can I not skip doing so in server.js entirely and just set the connection in the model script itself? What's the point of importing it and configuring a connection along with the rest of the server config when I'm only going to use it when working with the schema? And If the answer is yes, why doesn't anyone do that? Is there a performance benefit at play here?
You could do mongoose.connect() in your model script but this would not be advisable.
You would have to ensure that this model was loaded before any other scripts that required the mongoose connection.
If you go on to create another model in your application, then this would rely on your User model (model.js) having been loaded first.
You would have to perform the connection in each model just to be sure, but this would be a poor design and unnecessary code duplication.
Therefore, connecting in server.js is the best approach to ensure the connection is established as early as possible.
It is not necessary that you require the mongoose in the server.js file. In fact in my project I create a separate file for each connection like connection_one.js, connection_two.js and export the mongoose object. This way when any number of models does a require("./connection_one.js") it will return the same connection ready mongoose for all models exporting it. This is possible due to modules are cached on first time load inside a project. It is what is also happening when you are loading the mongoose module in server.js, it is the same mongoose object in server.js and model.js.
To address you question, first of all you need to understand object-oriented programming. Right now, you have two different files. One if server.js. and another is models.js. And each file has it's own scope.
Even if you imported mongoose in server.js since the two scopes has different scope set, models.js cannot utilize the mongoose service imported in server.js. For example, let say you defined a variable "foo",
You cannot use that variable in model.js because their scopes are isolated.
// server.js
const foo = 'bar';
If you want to use only one mongoose imported in a single script and shared by others, you can use global object from Node.js env. Check out the url to know more about this.
node.js global variables?
However, I don't really recommned putting mongoose service in gloabl object. Global scope can be easy at the beginning, but it could be significant scalability problem as your application grows bigger in later time.
Thanks.

Multi tenant (SAAS) using nodejs sequelize

I am trying to build a multi tenant ( / Software as a service) using nodejs and postgres, sequelize as ORM. I decided to go with separate DBs for each client, rather than having single DB with all table having the extra column, because of security reasons. I achieved the result, but performance was not good, since i have to initialise models for each DB according to sequelize(for almost each request). Is there any better way to do this? Am I missing something in sequelize?
A quick implementation of my comment above.
app.js:
const Sequelize = require('sequelize');
const connections = {
client1: new Sequelize('postgres://user:pass#example.com:5432/client1'),
client2: new Sequelize('postgres://user:pass#example.com:5432/client2'),
client3: new Sequelize('postgres://user:pass#example.com:5432/client3'),
};
const User = require('./models/user');
const Post = require('./models/post');
const Comment = require('./models/comment');
Object.keys(connections).forEach(connection => {
connection.define('User', userColumns);
connection.define('Post', postColumns);
connection.define('Comment', commentColumns);
});
models/user.js:
module.exports = {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
username: Sequelize.STRING,
email: Sequelize.STRING
// etc, etc
};
Obviously whatever server framework you use you'll need to detect (from the url I imagine) which client connection to use for a given request.
Alternatively, consider writing a single-connection app and deploying multiple instances of it (I'm doing this currently). Might be a simpler choice if you're set on separate DBs.
I prefer the schema approach to multi tenancy in Postgres. I'm no authority on security but it should be better than table based multi tenancy. Disaster recovery should also be slightly easier than table based MT, but still worse than with separate DBs.
I managed to implement this in Sequilize using ES6 Proxies. This puts a hard requirment on your Node version, but if you're willing to use at least v6.9.2 you could give my lib a try:
https://www.npmjs.com/package/sequelize-multi-tenant-enhancer

How to use MongoDB with mean.io

I am new to server side javascipt. I have started with mean.io. I gained some understanding of nodejs, express, mongodb last few days. I have my mean.io app but I don't know what's the right way to connect to mongodb and query it from my js files.
Is there a guide/blog which can help me work with mongodb from my server side javascript files?
All I want is to store some data mongodb and fetch that at some later point.
By default, you should see there is a mean-dev collection in your mongodb. The best way I thought to get familiar with mongo and mean is play around the code (for instance, the article package). Inside /packages/article/system/, you will see how the blog example works.
That works great for me.
I couldn't find one related to mean.io but below few links helped me get started with mean.io.
http://cwbuecheler.com/web/tutorials/2013/node-express-mongo/
https://www.youtube.com/watch?v=AEE7DY2AYvI
https://www.youtube.com/watch?v=5e1NEdfs4is
Edit:
Past few days I have been working on it and by test & learn I was able to got things working for me. I'll share whatever I know till now.
So mean.io use mongoose ODM to connect to the mongodb.
mean.io would automatically connect to your DB. You can configure DB name in development.js db: 'mongodb://localhost/myDB'. So you won't have to worry about connecting to mongoDB. You just need to start the mongoDB using mongod.
How to use mongoose?
To use mongoose to connect to mongoDB you need to build schemas. You can do so in myApp/app/models directory, since they represents models.
Sample model file user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: String,
email: String,
DOB : Date,
address: {
house_no: String,
street: String
}
});
module.exports = mongoose.model('tbl_user',userSchema);
Note:- tbl_user would be stored as tbl_userS in DB.
How to save data to mongoDB?
One would generally do save to DB in controller. Below I have shown how one can do this.
To make models available to all controller one need to write this piece of code in server.js so that all your models get registered during server startup. Alternatively, import individual models using require('tbl_user').
Server.js :-
var models_path = __dirname + '/app/models';
var arrFiles = fs.readdirSync(models_path);
arrFiles.forEach(function(file){
if(file.indexOf('.js') > 0){
require(models_path + '/' + file);
}
});
controller code myApp/app/controllers/myController.js
var mongoose = require('mongoose');
var jsonEntry = {'name':'Mady', 'email':'xyz#xyz.com', 'address':{'house_no':12N, 'stree':'abc'}};
var User = mongoose.model('tbl_user');
var user = new User(jsonEntry);
user.save();
The above code would create and update the tbl_users collection in mongoDB.

Referencing NodeJS MongoDB connection from AngularJS

I'm trying to set up a small development environment consisting of a node.js http server, a mongodb database and frontend in angular.js. For development purposes I've created an account with MongoHQ and can reference my db using a URL.
The issue I'm faced with is that I can easily connect to my db from my Angular code but then my connection info is exposed through my http server.
So what I would like to be able to is to create my connection in my NodeJS server.js file and reference it from eg. my AngularJS app.js file. Is that possible and if so how?
Thanks in advance
Try using express and mongoose.
Server side code
var express = require('express');
var app = express();
//start server with port of choice here
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var Foo=mongoose.model('foo');
//foo is a model. Check mongoose documentation from collections and schemas
app.get('/hello', function(req, res){
//get data from mongo using mongoose
foo.find({},function(err,docs){
//do stuff here
res.send(docs)
})
});
Front end code
$http.get('/hello').success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
//data is the data from mongodb
})
Follow this tutorial to get an idea
There is a stack called MEAN Stack. See if it fits your needs. Very easy to set up and develop.

Resources