Express – meilleur modèle pour la transmission de données entre les fonctions middleware

Je viens juste de parler de ce problème avec Express et je suis intéressé par ce que StackOverflow en pense:

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

Ma question est la suivante: pourquoi Express choisit-il d’empêcher le développeur de transmettre des données directement entre les fonctions de middleware et vous oblige fondamentalement à affecter des données temporaires à l’object de requête dans ce que j’ai toujours considéré comme une tâche assez délicate

Pour être plus précis:

transmettre des données entre les fonctions middleware implique généralement de le faire

req.specialData = {} next(); 

cependant, ce serait peut-être beaucoup plus facile et plus performant (!) si cela était possible

 next(null,data); 

ou

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

// maintenant, appelle la fonction ci-dessus

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

le problème est qu’Express utilise un moyen stupide, ce que je crois, de déterminer si l’appel est destiné à une fonction de middleware normale ou à la première fonction de middleware d’erreur suivante, en vérifiant si la fonction function.length> 3 ou la fonction function.length === 4 …

y a-t-il une chance que ce que je dis ait un sens?

Ne serait-il pas préférable / plus facile / plus rapide / plus fort d’autoriser le transfert direct de données via des fonctions middleware au lieu d’atsortingbuer des données maladroitement à req ??

Peut-être qu’Express a déjà cette capacité et que je suis simplement mal informé?

Ma question est la suivante: pourquoi Express choisit-il d’empêcher le développeur de transmettre des données directement entre les fonctions de middleware et vous oblige fondamentalement à affecter des données temporaires à l’object de requête dans ce que j’ai toujours considéré comme une tâche assez délicate?

Je pense donc que l’API est la solution idéale pour encourager la plupart des middlewares à être modulaires, réutilisables et à couplage faible. Cela signifie que le plus souvent devrait faire quelque chose sans trop se préoccuper de ce que les autres intergiciels pourraient exécuter avant ou après eux. Pour y parvenir et créer un écosystème de fonctions middleware peu compatibles, Express conserve l’API assez générique. Il y a des avantages et des inconvénients à cela. Mais pour répondre directement à votre première question, je dirais de garder l’interface simple, cohérente et flexible et d’éviter les dépendances ssortingctes des commandes.

Comme dans votre cas, il peut exister des dépendances implicites entre les middlewares. Un autre exemple courant serait généralement que votre middleware de session ait une dépendance implicite que votre middleware de cookie exécute avant. Avoir ces implicites tous implicites peut être discuté pour créer des bogues et des dépannages inutiles D’autre part, il permet aux développeurs d’applications de combiner plus facilement des middlewares qui autrement n’auraient peut-être aucune connaissance les uns des autres.

Avec le recul, je pense que moi-même ainsi que certains responsables de la maintenance express conviendraient qu’utiliser l’arité de la fonction (nombre d’arguments attendus) pour des raisons d’API sémantique constituait un choix étrange et médiocre de la part de TJ. Je pense que si le projet devait être réécrit, une API plus explicite serait définie pour la gestion des erreurs.

Ne serait-il pas préférable / plus facile / plus rapide / plus fort d’autoriser le transfert direct de données via des fonctions middleware au lieu d’atsortingbuer des données maladroitement à req ??

Mieux, c’est hautement discutable et fondé sur les opinions. Il y a beaucoup à dire sur la simplicité, et l’écosystème énorme et son utilisation en sont la preuve. Il existe des alternatives telles que hapi, restify, etc., mais vous pouvez les envisager.

Plus facile – probablement pas. Ce qui est là est assez facile.

Plus rapide – probablement pas de manière significative. Vous ne savez pas pourquoi votre version serait plus rapide, mais il est préférable d’apporter des indicateurs lorsque vous faites de telles affirmations.

Plus fort – Si vous entendez «plus fort», vous voulez dire plus explicitement, c’est probablement vrai, mais il y a une raison pour laquelle certaines personnes préfèrent encore JavaScript, même si TypeScript existe jusqu’à Haskell existe et est certainement plus «fort» dans un sens du mot.

Il existe peut-être des avantages à ce que fait Express. Toutefois, il convient de noter qu’Express permet la transmission de données entre middlewares à l’aide de res.locals. Cela dit, votre question m’a inspiré pour faire cette bibliothèque. Expressjs-plus. Grâce à cela, vous pourrez facilement faire passer des données entre vos middlewares sans avoir à utiliser la requête ni l’object de réponse.

Vous pouvez utiliser des fonctions javascript classiques, par exemple une fonction (varInResLocals, varInReqParams, callback) au lieu d’une signature de middleware express.

Voici un exemple de travail pour vous.

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