admin管理员组文章数量:1426066
This question is haunting me since long time and i've never found a answer that explained to me this clearly.
I'm using Express 4.0 and i've made this snippet to show you the solution that i've made, to get the result that i've needed.
I want to pass the argument req.method
and one array of routes controllers.routes
directly into the express router to define the method and to filter routes as it es in the middleware.
var controller = require( './controllers' );
module.exports = function ( app ){
app.router.use(function ( req, res, next ){
// function with the args before router get called
anotherFn( app, req.method, controller );
// Call the express router after called function with args
next( 'route' );
});
};
function anotherFn( app, method, controller ){
// Express router called with args here...
app.router[ method ]( controllers.routes,
function ( req, res, next ){
try{
controller[ req.config.action ]( req, res, next );
}catch( e ){
next( 'error' );
}
}
);
};
Its working at the moment, but it seems to me a little hacky or sketchy cause i think that the function never get resolved or the middleware calls for the route after calling the anotherFn
function and its strange how is it working and doesn't seem a good practice.
I'm afraid that in the future this could give me problems with asynchronism or could be hard to maintain cause doesn't seem solid code ( or at least for me ).
Now my question is, if this is a good practice and i can keep this as it is or if there is another way to pass this arguments to the router that doesn't seem so hacky and strange.
This question is haunting me since long time and i've never found a answer that explained to me this clearly.
I'm using Express 4.0 and i've made this snippet to show you the solution that i've made, to get the result that i've needed.
I want to pass the argument req.method
and one array of routes controllers.routes
directly into the express router to define the method and to filter routes as it es in the middleware.
var controller = require( './controllers' );
module.exports = function ( app ){
app.router.use(function ( req, res, next ){
// function with the args before router get called
anotherFn( app, req.method, controller );
// Call the express router after called function with args
next( 'route' );
});
};
function anotherFn( app, method, controller ){
// Express router called with args here...
app.router[ method ]( controllers.routes,
function ( req, res, next ){
try{
controller[ req.config.action ]( req, res, next );
}catch( e ){
next( 'error' );
}
}
);
};
Its working at the moment, but it seems to me a little hacky or sketchy cause i think that the function never get resolved or the middleware calls for the route after calling the anotherFn
function and its strange how is it working and doesn't seem a good practice.
I'm afraid that in the future this could give me problems with asynchronism or could be hard to maintain cause doesn't seem solid code ( or at least for me ).
Now my question is, if this is a good practice and i can keep this as it is or if there is another way to pass this arguments to the router that doesn't seem so hacky and strange.
Share Improve this question edited Sep 22, 2015 at 20:35 Obzzen asked Sep 22, 2015 at 11:25 ObzzenObzzen 1781 gold badge5 silver badges16 bronze badges 1- please, write what are your intentions. What you want to achieve? Looking at your code i see that you want to build routes for controllers and actions in controllers, is that correct? I dont understend why you register new routes in request. Please dont answer ment but edit your question. – Krzysztof Sztompka Commented Sep 22, 2015 at 21:23
1 Answer
Reset to default 7tl;dr
You must keep in mind that you must have 2 stages on an MVC based node server: Configuring stage and Working stage; which are the construction base for the 7 abstraction processing layers: Network Server (http/https/spddy/...), Request/Response Middleware system (express/connect), Router and Routes (Express Router, Simple router, emvici router), Controller, Model (mongo-cli/sequelize/...) and finally View (jade/ect/mustache/...)
All abstraction layers should be initialized and configured before going into a working stage. If your server is already receiving requests and perhaps Views aren't working yet, they will be producing errors. You're configuring Router/Routes inside the Router working state.
Seems that are some miss understanding concepts over there. Middlewares are used to be executed per each request. Controllers (supposing MVC here) are meant to save actions per each kind of data. Usually with an MVC pattern you always have a Router/Routes, some frameworks do that under the hood, others give you access to do so.
Happens that Express and mostly most well known nodejs modules are great for not following entirely the concept of a framework, they provide features around their goals but they provide only basic API stuff to let you glue with others. Thats the reason why you found various tutorials on google for the same propose but with pletely different implementations.
Now, back on track to your doubt, the binding between Controllers and the Router should be done by creating Routes. The way you're doing, you're adding routes into express every time someone does a request, and thats a memory intensive/bad approach.
I advise you to think in an abstraction layer before you start coding on that. Lets suppose you need Controllers, Models, Views, one Router, one Http Server (not app yet) and a app (usually app is a middleware connection part, could be connect
, express
and so on...)
- server.js - here you could abstract about you service, thats the place to choose if it would be an http/https/spdy and so on...
- app.js - App should grab all requests from the server, pass them trough a group of middlewares you need and last but not least, router as a middleware
- router.js - When requests hit router, they should be already with all the data you need, now its time to redirect them to a route. For that to happen, router should have their routes configured and ready. Here you should require
routes
- routes/
- index.js - here you can export all routes you have on this folder, or if you prefer, configure them here. Each route can require the needed controller.
- controllers/ - you may not need an index since each route is requiring each controller. On each controller you could require needed Model and View.
- models/ - you may not need an index since each controller that needs a model is requiring them.
- views/ - views are meant to be required by the controller, but on express case, they have a View Engine that does that. Take a look on their docs for further details
Now something more codeific to your case:
server.js
var http = require( 'http' )
var server = http.createServer()
module.exports = server
app.js
var server = require( './server' )
var app = require( 'express' )()
module.exports = app
// Grab middlewares here...
// ...
// Now configuring router
app.use( require( './router' ) )
app.listen( server );
router.js
var router = new require( 'express' ).Router()
module.exports = router
// Load routes
require('./routes' ).forEach(function ( route ) {
route( router )
})
routes/index.js
exports.user_example = require( './user_example' )
user_example.js
var UserController = require( '../controller/user' )
module.exports = function ( router ) {
router
.route( '/user' )
.post(UserController.create)
.put(UserController.create)
;
router
.route( '/user/:id' )
.get(UserController.view)
.post(UserController.update)
.put(UserController.update)
;
router
.route( '/user/delete/:id' )
.get(UserController.delete)
;
}
controller/user.js
// Here you should bind your modules
exports.create = function ( req, res, next ) {
res.send( 200, 'created' )
}
exports.view = function ( req, res, next ) {
res.send( 200, req.param( 'id' ) )
}
exports.update = function ( req, res, next ) {
res.send( 200, req.param( 'id' ) )
}
exports.delete = function ( req, res, next ) {
res.send( 200, req.param( 'id' ) )
}
Hope it helped! José Moreira
本文标签: javascriptPassing arguments from middleware to express routerStack Overflow
版权声明:本文标题:javascript - Passing arguments from middleware to express router - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745469416a2659681.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论