Sailsでは、**config/routes.js** ファイル内で、いくつかの異なる方法でURLを明示的にルーティングできます。各ルーティング設定は、**アドレス**と**ターゲット**で構成されます。例:
'GET /foo/bar': 'UserController.subscribe'
^^^address^^^ ^^^^^^^^^^target^^^^^^^^^^
ルートアドレスは、ハンドラーとターゲットで定義されたオプションを適用するために一致させる必要があるURLを示します。ルートは、オプションの動詞と必須のパスで構成されます。
'POST /foo/bar'
^verb^ ^^path^^
動詞が指定されていない場合、ルートは任意のCRUDメソッド(**GET**、**PUT**、**POST**、**DELETE**、または**PATCH**)と一致します。動詞として`ALL`が指定されている場合、ルートは*任意の*メソッドと一致します。
パスの先頭の`/`に注意してください。正しく動作させるには、すべてのパスの先頭に`/`が必要です。
**foo/bar**のような静的パスを指定することに加えて、ワイルドカードとして`*`を使用できます。
'/*'
はすべてのパスマッチしますが、
'/user/foo/*'
は** /user/foo**で始まるすべてのパスマッチします。
**注意:** `'/*'`などのワイルドカードを含むルートを使用する際は、静的アセット(例:`/js/dependencies/sails.io.js`)へのリクエストにも一致し、それらを上書きすることに注意してください。これを防ぐには、下記で説明されている `skipAssets` オプションの使用を検討してください。
最新のSailsアクションでこのワイルドカード(`*`)に対応するランタイム値を受け取るには、アクション定義の最上位レベルで`urlWildcardSuffix`を使用して、動的値を表すために使用する入力の名前を示します。
urlWildcardSuffix: 'template',
inputs: {
template: {
description: 'The relative path to an EJS template within our `views/emails/` folder -- WITHOUT the file extension.',
extendedDescription: 'Use strings like "foo" or "foo/bar", but NEVER "foo/bar.ejs" or "/foo/bar". For example, '+
'"internal/email-contact-form" would send an email using the "views/emails/internal/email-contact-form.ejs" template.',
example: 'email-reset-password',
type: 'string',
required: true
},
},
fn: async function({ template }) {
// …
}
- あるいは、従来の(req,res)アクションでは、`req.param('0')`を使用して、ルートのURLワイルドカードサフィックス(`*`)の動的値にアクセスできます。
- 詳細は、https://www.npmjs.com/package/machine-as-actionを参照してください。
アドレスの一部を取り込むもう1つの方法は、**パターン変数**を使用することです。これにより、`*`の代わりに` :paramName`パターン変数構文を使用して、*決して`/`文字を含まない*特別な名前付きパラメーターと一致するルートを作成できます。
'/user/foo/bar/:name'
オプションのパスパラメーターの場合は、パターン変数の最後に`?`を追加します。
'/user/foo/bar/:name?'
これは` /user/foo/bar/*`とほぼ同じリクエストにマッチしますが、ルートURLの動的部分の値をパラメーター値としてルートハンドラーに提供します(例:`req.param('name')`)。
ワイルドカード(`*`)構文はスラッシュと一致しますが、URLパターン変数(`:`)構文は一致しません。上記の例では、ルートアドレス`GET /user/foo/bar/*`の場合、` /user/foo/bar/baz/bing/bong/bang`などのURLを持つ着信リクエストは一致しますが(` :name`構文を使用した場合、同じURLは一致しません)。
パターン変数の一般的なユースケースは、スラッグまたはバニティURLのデザインです。たとえば、GithubのリポジトリのURL、http://www.github.com/balderdashy/sails
を考えてみましょう。Sailsでは、このルートを**`config/routes.js`ファイルの一番下に**次のように定義できます。
'get /:account/:repo': {
controller: 'RepoController',
action: 'show',
skipAssets: true
}
`RepoController`の`show`アクションでは、`req.param('account')`と`req.param('repo')`を使用して適切なリポジトリのデータを探し出し、ビューにlocalsとして渡します。`skipAssets`オプションにより、バニティルートが誤ってアセット(例:`/images/logo.png`)と一致しないようにし、アセットにアクセスできるようにします。
ワイルドカードアドレス構文に加えて、正規表現を使用してルートが一致する必要があるURLを定義することもできます。正規表現を使用してアドレスを定義する構文は次のとおりです。
`r|<正規表現文字列>|<パラメーター名のカンマ区切りリスト>`
これは文字「**r**」に続いてパイプ文字`|`、デリミタのない正規表現文字列、別のパイプ、および正規表現内の括弧で囲まれたグループにマップする必要があるパラメーター名のリストです。例:
`r|^/\d+(\w+)(\w+)$|foo,bar": "message/my-action`
これは`/123/abc/def`に一致し、**api/controllers/message/my-action.js**のアクションを実行し、値`abc`と`def`をそれぞれ`req.param('foo')`と`req.param('bar')`として提供します。
`\d`と`\w`の二重バックスラッシュに注意してください。このエスケープは、正規表現が正しく機能するために必要です!
**config/routes.js**ファイルにアイテムを任意の順序で追加できますが、Sailsは内部的にルートを*包括性*でソートすることに注意してください。包括性とは、アドレスが処理できる潜在的なリクエストの数です。一般的に、動的コンポーネントを含まないアドレスを持つルートが最初に一致し、次に動的パラメーターを持つルート、最後にワイルドカードを持つルートが続きます。これにより、ルートがお互いをブロックすることが防止されます(たとえば、`/*`ルートをリストの先頭に置くと、すべてのリクエストに応答し、他のルートは決して一致しなくなります)。
正規表現アドレスがある場合、指定した順序のままになります。たとえば、**config/routes.js**ファイルに`GET /foo/bar`ルートが続き、`GET r|^/foo/\d+$|`ルートがある場合、2番目のルートは常に`GET /foo/bar`の直後にソートされます。これは、正規表現ルートの包括性を決定するのが非常に困難であるためです。これらのルートを指定する際には、意図したよりも多くのリクエストに一致しないように順序に注意してください。
カスタムルートのアドレス部分は、ルートが一致する必要があるURLを指定します。*ターゲット*部分は、一致が作成された後にSailsが実行する必要がある操作を指定します。ターゲットは、いくつかの異なる形式をとることができます。場合によっては、配列に配置することで、複数のターゲットを1つのアドレスにチェーンしたい場合がありますが、ほとんどの場合、各アドレスには1つのターゲットのみがあります。さまざまなタイプのターゲットについて以下で説明し、その後、それらに適用できるさまざまなオプションについて説明します。
この構文は、ルートをコントローラーファイルのアクションにバインドします。次の4つのルートは同等です。
'GET /foo/go': 'FooController.myGoAction',
'GET /foo/go': 'foo.myGoAction',
'GET /foo/go': { controller: 'foo', action: 'myGoAction' },
'GET /foo/go': { controller: 'FooController', action:'myGoAction' },
それぞれ、**api/controllers/FooController.js**内、または**api/controllers/foo/mygoaction.js**内にあるコントローラーの`myGoAction`アクションに`GET /foo/go`をマップします。そのようなコントローラーまたはアクションが存在しない場合、Sailsはエラーメッセージを出力し、ルートを無視します。それ以外の場合は、** /foo/go**への**GET**リクエストが行われるたびに、そのアクション内のコードが実行されます。
この構文のコントローラー名とアクション名は、大文字と小文字が区別されません。
この構文は、アドレスをスタンドアロンのSailsアクションにバインドします。アクションのパス(`api/controllers`からの相対パス)を指定するだけです。
'GET /': { action: 'index' }, // Use the action in api/controllers/index.js
'GET /foo/go': { action: 'foo/go-action' } // Use the action in api/controllers/foo/go-action.js OR
// the "go-action" action in api/controllers/FooController.js
'GET /bar/go': 'foo/go-action' // Binds to the same action as above, using shorthand notation
ブループリントAPIは、各モデルにいくつかのアクションを追加します。これらはすべてルーティングに使用できます。たとえば、`api/models/User.js`に定義されているモデルがある場合、自動的に次のことができます。
'GET /foo/go': 'user/find' // Return a list of users
または
'GET /foo/go': 'UserController.find' // Same as above
`api/controllers/user/find.js`または`api/controllers/UserController.js`にカスタムアクションがある場合、デフォルトのブループリント`find`の代わりにそのアクションが実行されます。モデルに提供されるアクションの完全なリストについては、ブループリントAPIリファレンスを参照してください。
もう1つの一般的なターゲットは、ルートをビューにバインドするターゲットです。これは、静的ビューをカスタムURLにバインドする場合に特に役立ち、新しいプロジェクトのデフォルトのホームページがすぐに設定される方法です。
ビューターゲットの構文は単純です。ファイル拡張子(例:`.ejs`)を除いたビューファイルへのパスで、**views/**フォルダからの相対パスです。
'GET /team': { view: 'brochure/about' }
これは、デフォルトのEJSテンプレートエンジンを使用していることを前提として、Sailsに` /team`への`GET`リクエストを`views/brochure/about.ejs`にあるビューテンプレートを提供するように指示します。そのビューファイルが存在する限り、** /home**への**GET**リクエストはそのビューを表示します。Express/consolidateとの整合性を保つため、指定された相対パスがビューファイルと一致しない場合、Sailsは同じ名前のサブフォルダ(例:`pages/brochure`)を探し、そのようなサブフォルダに「index」ビュー(例:`pages/brochure/index.ejs`)が存在する場合はそれを提供します。
このルートはビューに直接バインドされているため、構成されたポリシーは適用されないことに注意してください。ポリシーを構成する必要がある場合は、コントローラーアクションから`res.view()`を使用してください。このStackOverflowの質問で詳細な背景情報を確認できます。
Sailsアプリ内または別のサーバーで、あるアドレスを別のアドレスにリダイレクトできます。これは、リダイレクトURLを文字列として指定するだけで実行できます。
'/alias' : '/some/other/route/url',
'GET /google': 'http://www.google.com'
Sailsアプリ内でリダイレクトする場合は、リダイレクトループを避けるように注意してください!
リダイレクト時には、元のリクエストのHTTPメソッド(および追加のヘッダー/パラメーター)は失われ、リクエストは単純な**GET**リクエストに変換される可能性が高いことに注意してください。上記の例では、** /alias**への**POST**リクエストは、** /some/other/route**への**GET**リクエストになります。これはブラウザーに依存する動作ですが、リクエストメソッドやその他のデータがリダイレクトを乗り越えることを期待しないことをお勧めします。
この構文を使用して、アドレスをデフォルトまたはカスタムのレスポンスに直接マップできます。
'/foo': { response: 'notFound' }
**api/responses**フォルダにあるレスポンスファイルの名前を、**.js**拡張子なしで指定するだけです。この構文のレスポンス名は、大文字と小文字が区別されます。存在しないレスポンスにルートをバインドしようとすると、Sailsはエラーを出力し、ルートを無視します。
ほとんどの場合、**config/policies.js**設定ファイルを使用してポリシーをコントローラーアクションに適用します。ただし、特にビューターゲット構文を使用している場合、ポリシーをカスタムルートに直接適用したい場合があります。ポリシートゲット構文は次のとおりです。
'/foo': { policy: 'my-policy' }
配列を使用してポリシーを少なくとも1つの他のタイプのターゲットにチェーンする必要があることに注意してください。
'/foo': [
{ policy: 'my-policy' },
{ view: 'dashboard' }
]
これはルートにmy-policyポリシーを適用し、それがパスした場合、views/dashboard.ejsビューを表示して続行します。
ワンオフジョブ(例えば、迅速なテスト)の場合、ルートを関数に直接割り当てることができます。
'/foo': function(req, res) {
return res.send('hello!');
},
配列を使用して、この構文を他の構文と組み合わせることもできます。これにより、迅速なインラインミドルウェアを定義できます。
'/foo': [
function(req, res, next) {
sails.log('Quick and dirty test:', req.allParams());
return next();
},
{ controller: 'user', action: 'find' }
],
fn
キーを持つディクショナリを使用して、関数に割り当てることもできます。これにより、同時にその他のルートターゲットオプションを指定することもできます。
'GET /*': {
skipAssets: true,
fn: function(req, res) {
return res.send('hello!');
}
},
ベストプラクティスとしては、一時的なルートにのみ関数構文を使用することです。そうしないと、Sailsを便利にする構造上の規約に反することになります!(さらに、routes.jsファイルが整理されているほど、よいです。)
上記のさまざまなルートターゲット構文で説明されているオプションに加えて、ルートターゲットオブジェクトに追加されたその他のプロパティはすべて、req.options
オブジェクト内のルートハンドラーに渡されます。ルートハンドラの動作に影響を与えるために使用できる予約済みのプロパティがいくつかあります。これらは以下の表にリストされています。
プロパティ | 適用可能なターゲットタイプ | データ型 | 詳細 |
---|---|---|---|
skipAssets |
すべて | ルートがドットを含むURL(例:myImage.jpg)に一致しないようにする場合は、true に設定します。これにより、ワイルドカード表記を使用するルートが静的アセットのURLに一致しなくなります。URLスラッグを作成する場合に役立ちます。 |
|
skipRegex |
すべて | ドットを含むすべてのURLをスキップするのがあまりにも寛容すぎる場合、またはまったく異なる基準に基づいてルートのハンドラーをスキップする必要がある場合は、skipRegex を使用できます。このオプションを使用すると、リクエストURLと照合する正規表現または正規表現の配列を指定できます。一致が成功した場合は、ハンドラーがスキップされます。ハンドラーを正規表現でバインドする構文とは異なり、skipRegex は実際のRegExpオブジェクトを期待し、文字列は期待しません。 |
|
locals |
コントローラー、ビュー、ブループリント、レスポンス | リクエストの処理中にレンダリングされるビューに渡すデフォルトのローカル変数を設定します。 | |
cors |
すべて | 異なるオリジンからのこのルートのリクエストを処理する方法を指定します。詳細については、メインCORSドキュメントを参照してください。 | |
csrf |
すべて | リクエストでCSRFトークンを渡す必要があることによって、ルートを保護する必要があるかどうかを示します。詳細については、メインCSRFドキュメントを参照してください。 | |
parseBlueprintOptions |
ブループリント | ブループリントアクションのデフォルトの動作(検索条件、スキップ、制限、ソート、およびポピュレーションを含む)をオーバーライドするために、この関数を指定します。詳細については、ブループリント設定リファレンスを参照してください。 |