Архитектура приложений на основе Mongoose

Это не конкретный вопрос для приложения/кода, это просто общая архитектура приложений.

Я пытаюсь понять, как правильно организовать мое приложение для мангуста. Поскольку я новичок в мангусте, то как я это делаю сейчас:

ядро ​​/settings.js

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

ядро ​​/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)

ядро ​​/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');
        });
    });
});

<сильные > маршруты /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);

Итак, этот код был чрезвычайно упрощен (даже не проверен), чтобы показать мои текущие мысли архитектуры. Это не конкретное приложение, а просто создание абстрактного блога. Так вот как это работает:

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

Кажется, это немного излишне для меня. Не могли бы вы предложить более оптимальную структуру приложения? Спасибо.

Ответ 1

Когда я впервые попал в Node.js, Express и Mongoose, я боролся с масштабированием моего кода. Цель моего ответа - помочь кому-то, кто работает не только с простым блогом, но и с помощью еще большего масштабируемого проекта.

  • Я всегда подключен к базе данных, я не открываю и не закрываю соединения при необходимости
  • Я использую index.js в качестве корневого файла папки, как это было бы на других языках
  • хранятся в своих документах и ​​ require() d в файле models/index.js. Маршруты
  • аналогичны моделям, каждый уровень маршрута имеет папку, у которой в свою очередь есть файл index.js. Так что легко устроить что-то вроде http://example.com/api/documents/:id. Это также имеет смысл, когда вы просматриваете структуру файла.

Здесь структура того, что я использую:

-- 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)

мангуст /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

модели /index.js

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

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

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

модели /blog.js

Итак, для каждой модели, над которой вы работаете, вы создаете документ model.js и добавляете его в models/index.js выше. В качестве примера я добавил модель User, но прокомментировал ее.

// 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;

маршруты /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
}

маршруты/блог/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
}

предлагаемое использование

  • : для создания логики, связанной с документами, то есть создания, обновления, удаления и поиска.
  • маршруты: минимальное кодирование, только там, где мне нужно анализировать данные HTTP, создавать экземпляры моделей, а затем отправлять запросы к соответствующей модели.
  • : для более сложной логики, которая напрямую не связана с моделями. В качестве примера у меня есть папка algorithms/, где хранятся все алгоритмы, которые я использую в своем приложении.

Надеюсь, что это дает больше ясности. Эта структура творит чудеса для меня, поскольку мне легко следовать.

Ответ 2

Это в значительной степени, как я это делаю, с несколькими отличиями:

  • Я не думаю, что у вас может быть открытый слушатель внутри вашей функции в db-слое. То, что я обычно делаю при использовании постоянного соединения, такого как ваше, запускает само приложение в db open handler. Если вы не хотите использовать постоянные соединения, используйте createConnection в функции уровня db и убедитесь, что вы закрыли его перед вызовом обратного вызова. Я не уверен, что я проясняю. Дайте мне знать, если вы хотите использовать пример кода.
  • Это скорее общий совет node.js, но я держу свою строку подключения к базе данных и другую конфигурацию в json файле и требую ее везде, где это необходимо. После этого вам, вероятно, не понадобится другой файл settings.js.
  • Вы также можете использовать функции схемы (http://mongoosejs.com/docs/api.html#schema_Schema-method), чтобы закодировать некоторые функции приложения в самих моделях.