Comments 20
Насколько актуальной для вхождения остаётся эта книга: "Node.js для начинающих"? Что нужно дополнительно к ней (и в объёме по времени), чтобы полноценно работать с Нодой на сервере в области веб-приложений, при условии, что опыт на сервере и с БД есть?

Я, например, эту книгу почитал в своё время, но мой опыт с Нодой ограничился различными сборочными скриптами, и основной «книгой» были фактичесски «доки» по API. Нельзя сказать, что какое-либо «Введение» решительно помогло. А если идти с Нодой в веб-разработку, то что ещё нужно, какие книги?
Данную книгу не читал, поэтому трудно что-то сказать, не зная на чем сделан акцент. Точно могу сказать одно: API ноды изменилось с тех пор, некоторые методы стали не актуальными – могут возникнуть проблемы.
Можно пару вопросов?
1. А что будет если ваш сервер запустится и начнёт отвечать на запросы до того как случится коннект с монгой?
2. А что будет если коннект с монгой оборвётся на какое-то время?
1) в MongoClient.connect добавить что то вроде emit(«ready»), и делать server.listen после ready-ивента
2) всюда будет вылетать в callback(err)
В первом случае процесс упадет, так как значение переменной db – undefined. Во-втором, он так же упадет из-за ошибки соединения. Как обработать эти ситуации я расскажу позже.
Спасибо за статью, с нетерпением жду продолжения. Будет ли примеры работы с promise, а то пока не сильно справляюсь с асинхронностью запросов, в частности к DB…
а я вот хочу узнать следующую вещь:
объясните, зачем функции file и list присваиваются в конструкторе? почему они не устанавливаются через prototype?
ведь, если я не ошибаюсь, в данном случае при создании двух и более инстансов App в каждом и них под эти функции будет выделен отдельный кусок памяти.
Вы правы, при создании методов в конструкторе именно в каждом инстансе будут создаваться свои собственные методы, поэтому обычно методы делают через прототип.
Но в данном случае, класс App предназначен для инкапсуляции логики приложения, и не подразумевается в одном приложении создавать несколько объектов этого класса. Поэтому, автор решил поместить создание методов в конструктор, для наглядности, чтобы не плодить сложности в App.js.
Думаю, в реальном большом приложении все эти методы класса App будут разнесены в разные файлы, и подключаться в приложение из этих файлов.
Вы только в начале пути. В последнем своём проекте, о котором я напишу после его окончания, я сделал следующее:
1. Разделил собственно приложение (настройка express app) и функции, которые обрабатывают запросы (назвал их контроллёрами)
2. Функции-контроллёры получают список входящих параметров с помощью инъекций по полной аналогии с angular framework.

Т.е. просто применил MVC шаблон. Это реально освободило меня от шаблонного кода и я больше сосредоточен на логике функций-контроллёров.

Если схематично, то получается следующее:
// listCtrl.js
module.exports = listCtrl = function(request, response, app) {
};
listCtrl.$inject = ['request', 'response', 'app'];

// fileCtrl.js
module.exports = fileCtrl = function(request, response, app) {
};
fileCtrl.$inject = ['request', 'response', 'app'];

// app.js
var routes = [
  {
    path : '/',
    method : 'get',
    controller : require('./controllers/listCtrl.js')
  },
  {
    path : '/file',
    method : 'get',
    controller : require('./controllers/fileCtrl.js')
  }
];

// middleware которая набивает маршрутами и обработчиками express по модели, делает инъекции при вызове контроллёра и т.д.
express.use(router(routes));



Главным бонусом такого подхода является отличная тестируемость функций-контроллёров (из-за внедрения зависимостей). Когда закончу проект, посмотрю что получилось и выложу на суд общественности.
Да, модель angular очень крутая и я с ней сейчас работаю, но, пока, на уровне экспериментов. В вашем же случае вы объединяете логику и интерфейс, а я пишу о том, что этого делать не нужно.
Не совсем понял где Вы увидели у меня смешение интерфейса и логики? Может в моём коде не хватает комментариев для лучшего понимания…
1. Код конроллёров полностью вынесен из http-интерфейса. Я отметил в коде, что каждый контроллёр находится в отдельном файле и список его входных параметров чётко обозначен. Это даёт им хорошую тестируемость и переиспользование.
2. Код http-интерфейса практически не растёт с ростом методов. Увеличивается только модель интерфейса (в коде это routes). Таким образом отпадает надобность его тестировать вообще.

В вашем варианте у Вас всё-таки остаётся код в интерфейсе.
server.get('/file', function(req, res, next){
    app.file(req.query.file, function(err, file){
        if (err) return next(err);

        res.type('text/plain').end(file);
    });
});

Вам придётся написать на него тест. Но в таком варианте Вы этого сделать не сможете. Это довольно сложно. А сложных тестов быть не должно.

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

Единственное могу посоветовать, все-таки, использовать именованные функции в контролерах:
module.exports = FileCtrl;

FileCtrl.$inject=['request','response', 'app'];
function FileCtrl(req, res, app) {
    //...
}


По спецификации именованные функции объявляются сразу после парсинга кода.
В реальности так и делаю, здесь просто для краткости.
Хорошо, что отметили, пусть останется для читателей.
А у меня такой вопрос, почему для работы с MongoDB вы использутете MongoClient, а не Mongoose?
Не хотелось плодить сущности не относящиеся к основной идее. А вообще мне не нравятся схемы и валидация в mongoose, гораздо удобнее они реализованы в Waterline ORM.
Only those users with full accounts are able to leave comments. Log in, please.