技術的には、Sails アプリケーションで記述するコードの大部分はミドルウェアです。これは、着信リクエストと発信レスポンスの間に実行される、つまりリクエスト/レスポンススタックの「中間」で実行されることを意味します。MVCフレームワークでは、「ミドルウェア」という用語は、通常、ルート処理コード(つまり、コントローラーアクション)の前または後に実行されるコードをより具体的に指し、同じコードを複数のルートまたはアクションに適用できるようにします。Sailsは、ミドルウェア設計パターンを強力にサポートしています。必要に応じて、次のようなものを実装できます。
routes
機能を実装したフック—1つ以上のルートハンドラーの前にコードを適用するSailsは、req
、res
、next
を引数として受け取る関数であるExpress/Connectミドルウェアと完全に互換性があります。すべてのアプリは、HTTPリクエストを処理するための設定可能なミドルウェアスタックを使用します。アプリがHTTPリクエストを受け取るたびに、設定されたHTTPミドルウェアスタックが順番に実行されます。
このHTTPミドルウェアスタックは、「真の」HTTPリクエストにのみ使用されます。仮想リクエスト(例:ライブSocket.io接続からのリクエスト)には無視されます。
デフォルトでは、Sailsはいくつかの異なるミドルウェア関数を使用して、低レベルのHTTP関連タスクを処理します。これらは、クッキーの解釈、HTTPリクエストボディの解析、アセットの提供、さらにはアプリのルートの接続などです。デフォルトのミドルウェアスタックの詳細については、こちらを参照してください。
ミドルウェアスタックには妥当なデフォルトが付属しているため、多くのSailsアプリではこの設定を変更する必要はありません。しかし、より柔軟性が必要な状況では、Sailsを使用すると、アプリのHTTPミドルウェアスタック内の関数を簡単に追加、並べ替え、上書き、無効化できます。
新しいカスタムHTTPミドルウェア関数を設定するには、ミドルウェア関数をmiddleware
に新しいキー(例:「foobar」)として追加し、そのキーの名前(「foobar」)をmiddleware.order
配列に追加します。ミドルウェアチェーンの実行場所を指定します。
ミドルウェアスタックの順序を設定するために予約されている「order」を除き、sails.config.middleware
のキーに割り当てられた値は、req
、res
、next
の3つの引数をとる関数である必要があります。この関数はポリシーとほぼ同じように機能しますが、唯一の違いは実行されるタイミングです。
カスタムミドルウェア関数で一度限りのセットアップコードを実行する必要がある場合は、渡す前にそうする必要があります。これを行う推奨方法は、自己呼び出し(つまり、「すぐに実行される」)ラッパー関数を使用することです。以下の例では、値を「req、res、next」関数に直接設定するのではなく、自己呼び出し関数が使用されていくつかの初期セットアップコードを「ラップ」していることに注意してください。その自己呼び出しラッパー関数は、最終的なミドルウェア(req、res、next)関数を返します。そのため、直接渡された場合と同様に、キーに設定されます。
次の例は、3つの異なるカスタムHTTPミドルウェア関数を設定する方法を示しています。
// config/http.js
module.exports.http = {
middleware: {
order: [
'cookieParser',
'session',
'passportInit', // <==== If you're using "passport", you'll want to have its two
'passportSession', // <==== middleware functions run after "session".
'bodyParser',
'compress',
'foobar', // <==== We can put other, custom HTTP middleware like this wherever we want.
'poweredBy',
'router',
'www',
'favicon',
],
// An example of a custom HTTP middleware function:
foobar: (function (){
console.log('Initializing `foobar` (HTTP middleware)...');
return function (req,res,next) {
console.log('Received HTTP request: '+req.method+' '+req.path);
return next();
};
})(),
// An example of a couple of 3rd-party HTTP middleware functions:
// (notice that this time we're using an existing middleware library from npm)
passportInit : (function (){
var passport = require('passport');
var reqResNextFn = passport.initialize();
return reqResNextFn;
})(),
passportSession : (function (){
var passport = require('passport');
var reqResNextFn = passport.session();
return reqResNextFn;
})()
},
}
上記で説明した戦略を使用して、ボディパーサーなどの組み込みミドルウェアを上書きすることもできます(ボディパーサーのカスタマイズを参照)。
推奨されませんが、組み込みHTTPミドルウェア関数を完全に無効化することもできます。
middleware.order
配列から削除するだけです。これにより完全な柔軟性が得られますが、注意して使用する必要があります。組み込みミドルウェアを無効にする場合は、その結果を完全に理解してください。組み込みHTTPミドルウェアを無効にすると、アプリの動作が大きく変わる可能性があります。
Sailsアプリの本当に優れた点の1つは、既存のExpress/Connectミドルウェアを豊富に利用できることです。しかし、人々が実際にこれを実行しようとすると、よくある質問が生じます。
「この
app.use()
はどこで使用しますか?」.
ほとんどの場合、答えは、sails.config.http.middleware
でExpressミドルウェアをカスタムHTTPミドルウェアとしてインストールすることです。これにより、SailsアプリへのすべてのHTTPリクエストに対してトリガーされ、他のHTTPミドルウェアとの関係で実行順序を設定できます。
router
HTTPミドルウェアを上書きまたは削除しないでください。これはSailsに組み込まれており、これがないと、アプリの明示的なルートとブループリントルートは機能しません。
Expressミドルウェアを特定のアクションのみに適用するには、Expressミドルウェアをポリシーとして含めることもできます。ただし、HTTPと仮想ソケットリクエストの両方で実行する必要があることを確認してください。
これを行うには、config/policies.js
を編集して、実際のラッパーポリシー(通常は良い考えです)でミドルウェアをrequireして設定するか、policies.js
ファイルで直接requireします。次の例では、簡潔にするために後者の戦略を使用しています。
var auth = require('http-auth');
var basic = auth.basic({
realm: 'admin area'
}, function (username, password, onwards) {
return onwards(username === 'Tina' && password === 'Bullock');
});
//...
module.exports.policies = {
'*': [true],
// Prevent end users from doing CRUD operations on products reserved for admins
// (uses HTTP basic auth)
'product/*': [auth.connect(basic)],
// Everyone can view product pages
'product/show': [true]
}