Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
326 views
in Technique[技术] by (71.8m points)

node.js - Mongoose-based app architecture

This is not a concrete app/code question, it's just about common app architecture.

I'm trying to understand proper way to organize my mongoose application. As I'm new to mongoose, that's how I do it now:

core/settings.js

var mongoose = require('mongoose');
exports.mongoose = mongoose;
mongoose.connect('mongodb://localhost/blog');
exports.db = mongoose.connection;

core/models.js

settings = require("./settings");

// post schema
var postSchema = settings.mongoose.Schema({
    header: String,
    author: String,
    text: String
})

//compiling our schema into a Model 
exports.post = settings.mongoose.model('post', postSchema)

core/db-layer.js

settings = require("./core/settings");
models = require("./core/models");

exports.function = createAndWriteNewPost(function(callback) {
    settings.db.on('error', console.error.bind(console, 'connection error:'));
    settings.db.once('open', function callback() {
        new models.post({
            header: 'header',
            author: "author",
            text: "Hello"
        }).save(function(err, post) {
            callback('ok');
        });
    });
});

routes/post.js

db = reqiure("../core/db.js")

exports.get = function(req, res) {
    db.createAndWriteNewPost(function(status){
    res.render('add_material', {
      //blah blah blah        
        });
    });
};

app.js

var post = require ('routes/post.js')
...
app.get('/post', post.get);

So, this code was extremely simplified (even not tested) just to show my current architecture thoughts. It's not a concrete app, just something like creating an abstract blog post. So thats how it works:

app.js --> routes/post.js <--> core/db-layer.js
                                   |
                                   v
                               core/models.js <--> core/settings.js

It seems a bit over superfluous for me. Could you suggest more optimal app structure? Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When I first got into Node.js, Express and Mongoose I struggled with scaling my code. The intention of my answer is to help someone who's working on more than just a simple blog, but to help with an even larger scalable project.

  • I am always connected to the database, I do not open and close connections when needed
  • I use index.js as the root file of a folder, just like we'd do in other languages
  • models are kept in their own documents, and require()d into the models/index.js file.
  • routes are similar to models, each route level has a folder, which has an index.js file in turn. So it's easy to arrange something like http://example.com/api/documents/:id. It also makes more sense when one goes through the file structure.

Here's the structure of what I use:

-- app.js
-- models/
---- index.js
---- blog.js
-- mongoose/
---- index.js
-- routes/
---- index.js
---- blog/index.js
-- public/
-- views/
---- index.{your layout engine} => I use Jade.lang
-- methods/
---- index.js => use if you'd rather write all your functions here
---- blog.js => can store more complex logic here

app.js

var db = require('./mongoose'),
  express = require('express');
// note that I'm leaving out the other things like 'http' or 'path'
var app = express();

// get the routes
require('./routes')(app);
// I just require routes, without naming it as a var, & that I pass (app)

mongoose/index.js

// Mongoose connect is called once by the app.js & connection established
// No need to include it elsewhere
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/blog');

// I have just connected, and I'm not exporting anything from here

models/index.js

// Logic here is to keep a good reference of what's used

// models
Blog = require('./blog');
// User = require('./user');

// exports
exports.blogModel = Blog.blogModel;
// exports.userModel = User.userModel;

models/blog.js

So for every model that you work on you create a model.js document, and add it in the models/index.js above. As an example I've added a User model but commented it out.

// set up mongoose
var mongoose = require('mongoose');
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;

var BlogSchema = Schema({
  header: {type: String },
  author: {type: String },
  text: {type: String },
  _id: { type: ObjectId } // not necessary, showing use of ObjectId
});

Blog = mongoose.model('Blog', BlogSchema);
// the above is necessary as you might have embedded schemas which you don't export

exports.blogModel = Blog;

routes/index.js

module.exports = function(app) {
  app.get('/', function(req, res) {
    // do stuff
  });
  require('./blog')(app);
  // other routes entered here as require(route)(app);
  // we basically pass 'app' around to each route
}

routes/blog/index.js

module.exports = function(app) {
  app.get('/blog', function(req, res) {
    // do stuff
  });
  require('./nested')(app);
  // this is for things like http://example.com/blog/nested
  // you would follow the same logic as in 'routes/index.js' at a nested level
}

suggested use

  • models: for creating the logic that deals with the documents, i.e. creating, updating, deleting, and searching.
  • routes: minimal coding, only where I need to parse http data, create instances of models, and then I send queries to the relevant model.
  • methods: for the more complex logic that doesn't directly involve models. As an example, I have an algorithms/ folder where I store all the algorithms that I use in my app.

Hope this provides more clarity. This structure is working wonders for me as I find it easy to follow.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...