Как отделить маршруты и модели от 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
?
Ответы
Ответ 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.
Надеюсь, что это поможет.