Express – 在中间件function之间传递数据的更好模式

我刚刚提出了这个问题与快递,我感兴趣的是什么StackOverflow认为它:

https://github.com/strongloop/express/issues/2831

我的问题是为什么Expressselect不允许开发人员直接在中间件function之间传递数据,并基本上迫使您分配临时数据到请求对象,我一直认为这是一个相当尴尬的任务。

更具体:

在中间件function之间传递数据通常涉及这样做

req.specialData = {} next(); 

然而,如果这是可能的话,它可能会更容易,更高性能(!)

 next(null,data); 

要么

 function mySpecialMiddleWare(req,res,next,data){} 

//现在,调用上面的函数

 mySpecialMiddleWare(req,res,next, {some:data}); 

问题在于,Express使用了一个我认为是愚蠢的方式来确定调用是否是正常的中间件函数或下一个错误的第一个中间件函数,方法是检查function.length> 3或function.length === 4 …

有什么机会我说什么是有道理的?

如果通过中间件function直接传递数据,而不是笨拙地将数据分配给请求,会不会更好/更容易/更快/更强?

也许Express已经有这个function,我只是误导?

我的问题是为什么Expressselect禁止开发人员直接在中间件function之间传递数据,并基本上迫使您将临时数据分配给请求对象,而我一直认为这是一个相当尴尬的任务。

所以我认为API是鼓励大多数中间件模块化,可重用和松散耦合的方式。 这意味着通常应该做一些事情,而不必过于担心其他中间件可能在其之前或之后运行的其他中间件。 为了实现这一点并创build一个松散兼容的中间件function的生态系统,express使API保持相当通用。 这有利有弊。 但是作为对第一个问题的直接回答,我会说保持界面简单,一致和灵活,并尽量避免严格的顺序依赖。

就你而言,中间件之间可能存在隐式依赖关系。 另一个常见的例子是,你的会话中间件有一个隐含的依赖,就是你的cookie中间件在它之前运行。 这些都是隐含的可以被认为是造成错误和不必要的故障排除。 另一方面,它使应用程序开发人员能够更轻松地混合和匹配中间件,否则这些中间件可能不会彼此了解。

事后看来,我认为我和其他一些明确的维护者都会同意,在语义API原因中使用函数参数(期望的参数的数量)在TJ方面是一个奇怪而不好的select。 我认为如果项目被重写,更明确的API将被定义为error handling。

如果通过中间件function直接传递数据,而不是笨拙地将数据分配给请求,会不会更好/更容易/更快/更强?

更好 – 这是高度争论和舆论依据。 它的简单性有很多要说的,证据是巨大的生态系统和用法。 有替代品可用,如hapi,restify等,虽然你可能会考虑它们。

更容易 – 可能不会。 有什么是非常容易的。

更快 – 可能没有任何有意义的方式。 不知道为什么你认为你的版本会更快,但最好是在你提出这样的要求时提供指标。

更强 – 如果用“更强”的意思,则表示更明确,这可能是真的,但是有些人仍然喜欢使用JavaScript,尽pipeTypeScript一直沿着Haskell存在,并且在某种意义上肯定是“更强”的。

Express有什么好处,但是值得注意的是,Express允许在使用res.locals的中间件之间传递数据。 就这样说,你的问题激励我做这个图书馆。 Expressjs加。 有了它,您将能够轻松地在中间件之间传递数据,而无需使用请求和响应对象。

您可以使用常规的JavaScript函数,如函数(varInResLocals,varInReqParams,callback),而不是expression中间件签名。

这是你的一个工作的例子。

  var express = require('express'); var ExpressPlus = require('expressjs-plus').ExpressPlus; var app = express(); // simple handler example var userHandler = function(param, paramsArray, req, res){ if(param !== 'user') return false; paramsArray.push("USER WAS FOUND!"); return true; }; // this handler allows you to pass res.locals properties between your middlewares seemingly, // it the parameter was found in locals, it attaches it to paramsArray. var resLocalsHandler = function(param, paramsArray, req, res){ if(param in res.locals){ paramsArray.push(res.locals[param]); return true; }else return false; }; var appPlus = new ExpressPlus(app, [userHandler, resLocalsHandler], []); var regularFunction = function(user, id, cb){ return cb(null, { response: {user: user, id: id}, status: 200, resLocalsVar: "passVar" }); }; // resLocalsVar was passed in a previous method var regularFunction2 = function(resLocalsVar, user, id, cb){ // now you can have access to it console.log(resLocalsVar); return cb(null); }; // the responder at the end will use res.locals.status and res.locals.response to issue an HTTP response app.use(appPlus.GMV(regularFunction), appPlus.GMV(regularFunction2), appPlus.responder); // adds error handlers, it will add a default error handler along with the list of error handlers passed // in this case, no error handlers were passed appPlus.setErrorHandlers(); app.listen(3001, function(){ console.log('Listening!'); });