2017-06-02 5 views
0

Express.jsインスタンスといくつかの機能をラップしたいカップルのルートがあります。例:Express.js - 「デコレータ」内のすべてのミドルウェア/ルートをラップします

const wrapper = (route) => { 
    return (req, res, next) => { 
    let result = route(req, res, next); 

    // do some independent processing 
    } 
}; 

app.get('/', wrapper((req, res, next) => { 
    // respond to request somehow 
})); 

これが正常に動作している間、私は明示的にこのような処理を必要とするすべてのルートやミドルウェアwrapperを呼び出すためのアイデアを好きではありません。 Express.js延長、サル・パッチの適用や、いくつかの特別な経て、暗黙的に

wrapper関数は、このルート/ミドルウェアをラップする必要があることを確認することができますことを考えると)特定のラッパー内のすべての必要なルート/ミドルウェアをラップすることができるようにする方法はあります(ミドルウェア)?

UPDATE:

より固体の例。ルータの機能をasyncにしたいとしましょう。しかし、私は各ルート機能でエラーをキャッチしたくありません。だから私は彼らを包む:すべてのルートの周り

const wrapper = func => (req, res, next) => { 
    const promise = func(req, res, next); 

    if (promise.catch) { 
    promise.catch(err => next(err)); 
    } 

    next(); 
}; 

app.get('/one', wrapper(async (req, res, next) => { 
    // respond to request somehow 
})); 

app.get('/two', wrapper(async (req, res, next) => { 
    // respond to request somehow 
})); 

app.get('/three', wrapper(async (req, res, next) => { 
    // respond to request somehow 
})); 

// and so on... 

app.use((err, req, res, next) => { 
    // do something with intercepted error 
}); 

これ明示wrapperは、実際に私はを取り除きたいものです。

+0

ようREQ上のものを追加することができます

は、いくつかのコードを実行するためにあなたの究極の目標ですか? – robertklep

+0

いいえ、私の目標はルータ機能を装飾しているので、私は直接応答の結果を得ることができます(例えばPromiseを返す)。 – Nevertheless

答えて

2

最終的に、Expressはルートハンドラ関数の戻り値を伝播しないため、PITAのビットであることが判明しました。

const Layer   = require('express/lib/router/layer'); 
const handle_request = Layer.prototype.handle_request; 

Layer.prototype.handle_request = function(req, res, next) { 
    if (! this.isWrapped && this.method) { 
    let handle = this.handle; 
    this.handle = function(req, res, next) { // this is basically your wrapper 
     let result = handle.apply(this, arguments); 
     // do some independent processing 
     return result; 
    }; 
    this.isWrapped = true; 
    } 
    return handle_request.apply(this, arguments); 
}; 

私はおそらくかかわらexpress-promise-routerと同様のアプローチを使用することをお勧めし、ドロップイン置換Router Express用を実装します。これは私が(猿パッチ)を思い付いたものです

。しかし、暗黙のことではありません。

+0

答えをありがとう。しかし、これは単にルータ機能の戻り値に関連するだけではありません。より明示的な例で私の関数を更新してみましょう。 – Nevertheless

+0

@KidBinaryあなたが望むもの( 'if(result.catch){...}')を実装するために用意された例を使用するのは、とても簡単です。明らかに、これをユーティリティ関数に書き換えて、詳細を隠すこともできます。 – robertklep

+0

を参照してください。本当に問題は* PITAです:) – Nevertheless

0

なぜnext()を使用しないのですか?応答が送信されたとき、あなたは

app.get('/', (req, res, next) => { 
    req.somestupidfieldthatidontevenknowwhyinamedthisway = 42; 
    next(); 
}); 

app.get('/', (req, res, next) => { 
    //req.somestupidfieldthatidontevenknowwhyinamedthisway is now accessible as 42 
    var valueFromPreviousMiddleware = req.somestupidfieldthatidontevenknowwhyinamedthisway; 
    ..... 
}); 
+0

これは実際にはここでのポイントではないので、再度、ありがとうございます。私の質問を更新させてください。 – Nevertheless

関連する問題