Подтвердить что ты не робот

Как отделить маршруты и модели от app.js, используя NodeJS и Express

Я создаю приложение с помощью Node и Express. Тем не менее, я вижу, что скоро станет трудно управлять всеми маршрутами, расположенными внутри app.js. Я поместил все мои модели в подкаталог /models.

Здесь моя текущая структура приложения:

app.js
models
  -- products
  -- customers
  -- ...
public
views
node_modules

В app.js:

var express = require('express'),
    routes = require('./routes'),
    user = require('./routes/user'),
    http = require('http'),
    path = require('path'),
    EmployeeProvider = require('./models/employeeprovider').EmployeeProvider,
    Products = require('./models/products').Products,
    Orders = require('./models/orders').Orders,
    Customers = require('./models/customers').Customers,
    checkAuth = function(req, res, next) {
      if (!req.session.user_id) {
        res.send('You are not authorized to view this page');
      } else {
        next();
      }
    };

var app = express();

Затем некоторая конфигурация, такая как port, views каталог, механизм рендеринга и т.д.

Далее вниз app.js У меня есть маршруты:

app.get('/product/edit', auth, function(req, res) {
  Products.findAll(function(error, prds) {
    res.render('product_edit', {
      title: 'New Product',
      products: prds
    });
  });
});

В начало Я назначаю содержимое models/products.js переменной, все работает нормально. Однако сохранение всех маршрутов внутри app.js не является идеальным. Но если переместить маршруты на routes/product.js и загрузить модели Products:

var prod = require('../models/products.js');

Я получаю сообщение о том, что объект не имеет метода findAll.

Что я делаю неправильно? Как удалить маршруты из app.js?

4b9b3361

Ответ 1

В качестве выражения для выражения 4.x Router добавляется поддержка вашего дела.

Объект маршрутизатора представляет собой изолированный экземпляр промежуточного программного обеспечения и маршрутов. Вы можете думать об этом как о "мини-приложении", способном выполнять только промежуточное и маршрутизирующее функции. Каждое приложение Express имеет встроенный маршрутизатор приложений.

Пример из сайт expressjs:

// routes/calendarRouter.js

var express  = require('express');
var router = express.Router();

// invoked for any requested passed to this router
router.use(function(req, res, next) {
  // .. some logic here .. like any other middleware
  next();
});

// will handle any request that ends in /events
// depends on where the router is "use()'d"
router.get('/events', function(req, res, next) {
  // ..
});

module.exports = router;

Затем в app.js:

// skipping part that sets up app

var calendarRouter = require('./routes/calendarRouter');

// only requests to /calendar/* will be sent to our "router"
app.use('/calendar', calendarRouter);

// rest of logic

Ответ 2

Так как мне не нравится повторение, вот что я делаю:

// app.js
//...
var routes = requireDir('./routes'); // https://www.npmjs.org/package/require-dir
for (var i in routes) app.use('/', routes[i]);
//...

И каждый файл в маршрутах похож:

// routes/someroute.js
var express  = require('express');
var router   = express.Router();

router.get('/someroute', function(req, res) {
    res.render('someview', {});
});

module.exports = router;

Таким образом, вы можете избежать длинных повторяющихся списков, таких как:

app.use('/'           , require('./routes/index'));
app.use('/repetition' , require('./routes/repetition'));
app.use('/is'         , require('./routes/is'));
app.use('/so'         , require('./routes/so'));
app.use('/damn'       , require('./routes/damn'));
app.use('/boring'     , require('./routes/boring'));

Изменить: эти длинные примеры предполагают, что каждый файл маршрута содержит примерно следующее:

var router = express.Router();
router.get('/', function(req, res, next) {
    // ...
    next();
});
module.exports = router;

Все они могут быть установлены на "root", но для них "root", на самом деле это конкретный путь, заданный app.use, поскольку вы можете монтировать маршруты в определенные пути (это также поддерживает такие вещи, как указание путь с регулярным выражением, Express довольно аккуратен в отношении того, что вы можете сделать с маршрутизацией).

Ответ 3

Я могу предложить вам эту файловую структуру (согласно Модульные веб-приложения с Node.js и Express от tjholowaychuk):

app.js
   modules
      users
         index.js
         model.js
      users-api
         index.js
      static-pages
         index.js

user-api и static-pages экспортировать приложения expressjs, вы можете легко установить их в app.js. В модуле users вы можете описать некоторые операции доступа к данным и все методы управления с помощью объекта User (например, создание, обновление и т.д.). Наш API-модуль будет использовать все эти методы.

И вот пример кода файла app.js(без обычного экспресс-материала, только установочные маршруты из разных модулей):

var express = require('express');
var app = express();

// mount all the applications
app.use('/api/v1', require("user-api"));
app.use(require("static-pages"));

app.listen(3000);

Чтобы использовать ваши модули таким образом, вы должны запустить свое приложение следующим образом: NODE_PATH=modules node app.js (я поместил эту строку в файл package.json в разделе сценариев).

Вот пример кода модуля users:

index.js

User = require("./model");

module.exports = {
    get: function(id, callback) {
        User.findOne(id, function(err, user) {
           callback(err, user);
        });
    },
    create: function(data, callback) {
        // do whatever with incoming data here
        data = modifyDataInSomeWay(data);
        var newUser = new User(data);
        newUser.save(function(err, savedUser) {
            // some logic here
            callback(err, savedUser); 
        });
    }
};

model.js (например, с помощью материала Mongoose!)

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var User = new Schema({
    firstname   : {type: String, required: false},
    lastname    : {type: String, required: false},
    email       : {type: String, required: true}
});

module.exports = mongoose.model('user', User);

И пример модуля user-api (вот основная часть ответа о разделении маршрутов и моделей).

var users = require("users");

var express = require("express");
var app = module.exports = express(); // we export new express app here!

app.post('/users', function(req, res, next) {
    // try to use high-level calls here
    // if you want something complex just create another special module for this
    users.create(req.body, function(err, user) {
        if(err) return next(err); // do something on error
        res.json(user); // return user json if ok
    });
});

И пример static-pages. Если вы не собираетесь создавать своего рода интерфейс REST, вы можете просто создать несколько модулей, которые будут отображать только страницы.

var express = require("express");
var app = module.exports = express(); // we export new express app here again!

app.get('/', function(req, res, next) {
    res.render('index', {user: req.user});
});

app.get('/about', function(req, res, next) {
    // get data somewhere and put it in the template
    res.render('about', {data: data});
});

Конечно, вы можете делать все, что хотите, с помощью модулей. Основная идея expressjs - использовать множество небольших приложений вместо одного.

О модулях nodejs вы можете читать fooobar.com/info/181897/... и docs.

Надеюсь, что это поможет.