Как я могу структурировать свое экспресс-приложение, когда мне нужно только один раз открыть соединение mongodb? - PullRequest
16 голосов
/ 11 марта 2012

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

Проблема, с которой я столкнулся, довольно проста, но я в целом довольно новичок в этом, и у меня возникают проблемы с выяснением того, как правильно реализовать соединение с базой данных mongodb в приложении node / express.

Я использую Express 3.x и основываю макет моего приложения на этом проекте, предоставленном автором Express: https://github.com/visionmedia/express/tree/master/examples/blog

Я не заинтересован в создании блога, однако структура приложения выглядит довольно неплохо. Маршруты разделены, и все организовано хорошо.

Моя проблема в том, что у меня может быть 5-6 разных файлов js маршрута, и каждый файл js маршрута может иметь где-то от 1 до 15 маршрутов; из этих маршрутов 1 или 15 может потребоваться доступ к БД.

Так что моя проблема в том, что кажется действительно ужасной идеей делать db.open (...) каждый раз, когда я хочу запросить db. На данный момент я должен упомянуть, что я использую встроенный драйвер mongo-db (npm install mongodb).

Мне также нужно включить файл, подобный этому: http://pastebin.com/VzFsPyax

... во всех этих файлах маршрутов и во всех файлах моей модели. Тогда я также имею дело с десятками открытых десятков соединений.

Есть ли способ, которым я могу структурировать свое приложение таким образом, чтобы я устанавливал только 1 соединение, и оно оставалось открытым в течение сеанса (создание нового запроса для каждого запроса тоже было бы плохо)?

Если так, как я могу это сделать? Если вы знаете ответ, пожалуйста, опубликуйте пример кода, используя структуру блога tj (см. Ссылку в этом посте) в качестве базового руководства. По сути, есть способ, при котором маршруты и модели могут свободно использовать БД, находясь в отдельных файлах, чем открытый код БД.

Спасибо.

EDIT

Я достиг определенного прогресса в решении одной из моих проблем. Если вы посмотрите на пример блога tj, он инициализирует свои маршруты в app.js следующим образом:

require('./routes/site')(app);
require('./routes/post')(app);

И в файле маршрутов JS он начинается так:

module.exports = function(app){

Я наткнулся на проект ранее сегодня, когда я видел, как кто-то передавал 2 переменные в модуле module.exports call -> function (app, db). Тогда подумал, может ли это быть так просто, мне нужно просто настроить маршруты, чтобы они были (app, db) тоже? Да, это так.

Так что теперь часть 1 проблемы решена. Мне не нужно требовать файл mongo.js с образцом подключения в каждом файле маршрута. В то же время он достаточно гибок, и я могу решить, какие файлы маршрутов использовать ссылку на БД. Это стандартно и не имеет недостатка, верно?

Часть 2 проблемы (важная, к сожалению) все еще существует.

Как я могу обойтись без необходимости делать db.open (...) для каждого моего запроса и в идеале устанавливать соединение только один раз за сеанс?

Ответы [ 3 ]

16 голосов
/ 27 февраля 2013

Другое решение - передать базу данных маршрутизатору по запросу, например:

app.js

var db = openDatabase();

var app = express();

app.all('*', function(request, response, next)
    {
    request.database = db;
    next();
    });

app.get('/api/user/:id', Users.getByID);

users.js

var Users =
    {
    getByID: function(request, response)
        {
        request.database.collection('users').findOne(...)
        response.send(user);
        }
    };

module.exports = Users;
3 голосов
/ 11 марта 2012

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

В app.js вы можете создать соединение с БД один раз:

var hub = require('hub');
hub.db = new Db('foobar', new Server('10.0.2.15', 27017, {}), {native_parser: false});

И используйте его из любых других файлов:

var hub = require('hub');
// hub.db - here link to db connection

Этот метод использует функцию 'require'. Модуль загружается только в первый раз, а все остальные вызовы получают ссылку на уже загруженный экземпляр.

UPDATE

Вот что я имею в виду:

В основном файле, таком как app.js, мы создаем Db-соединение, открываем его и сохраняем в хабе:

app.js:

var hub = require('hub');
hub.mongodb = require('mongodb');
hub.mongodbClient = new hub.mongodb.Db('foobar', new hub.mongodb.Server('10.0.2.15', 27017, {}), {native_parser: false});
hub.mongodbClient.open(function(error) {
    console.log('opened');
});

Теперь в любом другом файле (например, в сообщении) у нас есть доступ к открытому соединению, и мы можем просто использовать его:

message.js:

var hub = require('hub');
var collection = new hub.mongodb.Collection(hub.mongodbClient, 'message');

module.exports.count = function(cb) {
    collection.count({}, function(err, count) {
        cb(err, count);
    });
};
1 голос
/ 15 марта 2012

Действительно глупо.В документации кажется, что db.open необходимо обернуть вокруг того, что его использует, но в действительности вы можете использовать его без обратного вызова.

Поэтому ответ заключается в том, чтобы просто выполнить db.open () вмодуль подключения к вашей базе данных, файл app.js или любое другое место, где вы решите настроить сервер / подключение БД.

Пока вы передаете ссылку на БД в файлах, которые его используют, вы будете иметь доступ к«открытое» соединение БД, готовое для запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...