javascript - 将参数从中间件传递到 express 路由器

标签 javascript node.js express

这个问题困扰了我很长时间,我从来没有找到一个能向我解释清楚的答案。

我正在使用 Express 4.0,我制作了这个片段来向您展示我制作的解决方案,以获得我需要的结果。

我想将参数 req.method 和一个路由数组 controllers.routes 直接传递到 express 路由器中,以定义方法并过滤路由在中间件中。

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' );
            }

        }
    );

};

它目前正在工作,但在我看来有点老套或粗略,因为我认为该函数从未得到解析,或者中间件在调用 anotherFn 函数后调用路由及其奇怪它是如何工作的,似乎不是一个好的做法。

我担心将来这可能会给我带来异步问题,或者可能难以维护,因为代码似乎不是可靠的(或者至少对我而言)。

现在我的问题是,如果这是一个好的做法并且我可以保持原样,或者是否有另一种方法将这个参数传递给路由器,这看起来并不那么古怪和奇怪。

最佳答案

tl;dr

您必须记住,在基于 MVC 的 Node 服务器上必须有 2 个阶段:配置阶段工作阶段;这是7个抽象处理层的构建基础: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/...) 最后查看 (jade/ect/mustache/...)

在进入工作阶段之前,应初始化和配置所有抽象层。如果您的服务器已经在接收请求并且 View 可能还没有工作,它们将产生错误。您正在 Router 工作状态下配置 Router/Routes。


那里似乎有些人没有理解概念。中间件用于根据每个请求执行。 Controller (这里假设为 MVC)旨在为每种数据保存操作。通常对于 MVC 模式,您总是有一个 Router/Routes,一些框架在后台执行此操作,而其他框架则允许您这样做。

碰巧 Express 和大多数最著名的 nodejs 模块非常适合不完全遵循框架的概念,它们提供围绕其目标的功能,但它们仅提供基本的 API 内容,让您与其他人联系在一起。这就是为什么您在 google 上找到了针对相同建议但实现方式完全不同的各种教程的原因。

现在回到你的疑惑,Controllers和Router之间的绑定(bind)应该通过创建Routes来完成。你这样做的方式是,每次有人发出请求时,你都会将路由添加到 express 中,这是一种内存密集型/糟糕的方法。

我建议您在开始编写代码之前考虑抽象层。假设您需要 Controller 、模型、 View 、一个路由器、一个 Http 服务器(还不是应用程序)和一个应用程序(通常应用程序是一个中间件连接部分,可能是 connectexpress等等...)

  • server.js - 在这里你可以抽象你的服务,如果它是 http/https/spdy 等等,那就是选择的地方......
  • app.js - 应用程序应该从服务器获取所有请求,通过一组您需要的中间件传递它们,最后但并非最不重要的是,路由器作为中间件
  • router.js - 当请求到达路由器时,它们应该已经包含了您需要的所有数据,现在是时候将它们重定向到路由了。为此,路由器应该配置并准备好它们的路由。在这里你应该要求 routes
  • 路线/
    • index.js - 在这里你可以导出你在这个文件夹中的所有路由,或者如果你愿意,在这里配置它们。每条路线都可能需要所需的 Controller 。
  • controllers/ - 您可能不需要索引,因为每条路线都需要每个 Controller 。在每个 Controller 上,您可能需要所需的模型和 View 。
  • models/ - 您可能不需要索引,因为每个需要模型的 Controller 都需要它们。
  • views/ - Controller 需要 View ,但在明确的情况下,它们有一个 View 引擎可以做到这一点。查看他们的文档以了解更多详细信息

现在对您的情况更具代码性:

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' ) )
}

希望对您有所帮助! 何塞·莫雷拉

关于javascript - 将参数从中间件传递到 express 路由器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32715607/

相关文章:

javascript - 重定义父类后,Javascript 对象实例如何保留方法?

windows - node.js,Windows 7,spawn chrome,无法设置用户数据目录

node.js - 使用node.js从mongoDB获取数据,连接有效但没有数据显示

node.js - 有没有办法检查是否刚刚使用 Okta 身份验证 API 创建了新帐户?

javascript - 如何使用 Node.js 在 Firebase 中注册用户?

javascript - 只想显示警告框 3 秒

javascript - 想要在wicket中调用js方法而不使用ajax的onclick或onsubmit按钮

javascript - 如何使 ReactJS 中的表格可排序?

Node.JS ExpressJS 异步与同步

javascript - 如何从discord API获取头像?