簡體   English   中英

Express - 在中間件函數之間傳遞數據的更好模式

[英]Express - better pattern for passing data between middleware functions

我剛剛用Express提出了這個問題,我對StackOverflow對它的看法感興趣:

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

我的問題是為什么Express選擇禁止開發人員直接在中間件函數之間傳遞數據,並且基本上迫使你將臨時數據分配給請求對象,我一直認為這是一個非常尷尬的任務。

更具體:

在中間件函數之間傳遞數據通常涉及這樣做

req.specialData = {}
next();

然而,如果這是可能的話,它可能會更容易和更高效(!)

next(null,data);

要么

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

//現在,調用上面的函數

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

問題是Express使用a,我認為是愚蠢的方式來確定調用是否是正常的中間件函數或下一個錯誤的第一個中間件函數,通過檢查是否function.length> 3或function.length === 4 ...

我有什么機會說得有道理嗎?

允許通過中間件函數直接傳遞數據而不是將數據笨拙地分配給req會不會更好/更容易/更快/更強?

也許Express已經具備了這種能力,我只是被誤導了?

我的問題是為什么Express選擇禁止開發人員直接在中間件函數之間傳遞數據,並且基本上迫使你將臨時數據分配給請求對象,我一直認為這是一個非常尷尬的任務。

所以我認為API是鼓勵大多數中間件模塊化,可重用和松散耦合的方式。 這意味着通常應該做一些事情,而不必過多關注其他中間件可能在它們之前或之后運行的內容。 為了實現這一目標並創建一個松散兼容的中間件功能的生態系統,express使API保持相當通用。 這有利有弊。 但作為對第一個問題的直接回答,我會說保持界面簡單,一致和靈活,並盡量避免嚴格的排序依賴。

在您的情況下,中間件之間可能存在隱式依賴關系。 另一個常見示例通常是您的會話中間件具有您的cookie中間件在其之前運行的隱式依賴。 擁有這些都是隱含的可以被認為是創建錯誤和不必要的故障排除。 另一方面,它使應用程序開發人員能夠更輕松地混合和匹配可能無法彼此了解的中間件。

事后我認為我和一些快速維護者都會同意,出於語義API的原因,使用函數arity(預期參數的數量)是TJ的一個奇怪和糟糕的選擇。 我認為如果要重寫項目,將為錯誤處理定義更明確的API。

允許通過中間件函數直接傳遞數據而不是將數據笨拙地分配給req會不會更好/更容易/更快/更強?

更好 - 這是非常有爭議和基於意見的。 它的簡單性有很多可以說的,證據是巨大的生態系統和使用。 有其他可用的選擇,如hapi,restify等,但你可能會考慮它們。

更容易 - 可能不是。 什么是非常容易的。

更快 - 可能沒有任何有意義的方式。 不確定為什么您認為您的版本會更快,但最好在您提出此類聲明時提供指標。

更強 - 如果通過“更強”你的意思更明確,這可能是真的,但有一個人仍然喜歡JavaScript,即使TypeScript一直通過Haskell存在,並且在某種意義上肯定“更強”。

Express正在做什么可能有優勢,但值得注意的是Express允許使用res.locals在中間件之間傳遞數據。 話雖如此,你的問題激勵我創建這個庫。 Expressjs加。 有了它,您將能夠輕松地在中間件之間傳遞數據,而無需使用請求和響應對象。

您可以使用常規的javascript函數,例如函數(varInResLocals,varInReqParams,callback),而不是表達中間件簽名。

這是一個適合你的工作示例。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM