2.ルーティング
2.1 スケルトンの初期状態
Expressジェネレータが生成したスケルトンは、下図のような構造で動作しています。
- HTTPリクエストを3000番ポートでListenします。
- HTTPリクエストの情報は、reqという名前のオブジェクトにセットされます。
- ルーティング機能が、URLのパスに応じて、処理のルートを振り分けます。
- TOPページの表示には、Viewエンジン(今回はEJS)が使われています。
- 静的ファイルへのリクエストは、/publicフォルダにルーティングされます。
- HTTPレスポンスは、resという名前のオブジェクトを使って返します。
この先は、このスケルトンを出発点として、いろいろな機能を肉付けしていくことになります。
2.2 アプリ起動からルーティングまでの流れ
アプリの起動からルーティング処理までの流れを見てみます。ターミナルから起動コマンド$ npm start
を実行すると、package.jsonのstart
に登録されているnode ./bin/www
が実行されます。
1 | ... |
/bin/wwwはHTTPサーバーを実行し、メインスクリプトのapp.jsと結びつけます。その後は、HTTPリクエストが発生する度に、URLのパスに対応したルーティングのハンドラが実行されます。
Expressでページを追加するときは、そのページのルーティングを設定し、ページの機能やビューと結びつけるといううことを行っていきます。
2.3 ルーティングとは
Expressアプリは、HTTPリクエストを受けとってレスポンスを返します。ルーティングとは、受け取ったURLのパスに対して、アプリでどんな処理をするのかという処理の流れを実装することです。例えば、エンドユーザーがアプリケーションに対して、http://localhost/users/というURLでアクセスしたとします。そのとき、/users/というパスに対してどのようなレスポンスを返すのか、アプリケーションで実装します。
Node.jsでWebアプリを作るのが初めての方にとっては、ルーティングを実装するという感覚が新鮮かもしれません。Node.js以外の言語を使う場合、ルーティング処理はApacheなどのWebサーバーが担当します。
また、Apacheなどの場合は、URLのパスとドキュメントルート以下の物理ファイルのパスは密接に関係していますが、Node.jsの場合は物理ファイルのパスを対応させることも、対応させないこともどちらも可能です。
Expressジェネレータが生成するスケルトンでは、静的なファイルに関してはpublicフォルダ以下に対応付けされており、プログラマが意識しなくても自動的にルーティングされます。動的な処理をするパスに関しては、プログラマがコードでルーティング処理を実装します。動的なルーティングの実装は、主にroutesディレクトリ以下に配置していきます。
2.4 静的ページのルーティング
静的ファイルに関しては/public/フォルダに割り当てられていますので、ここに簡単なHTMLページを配置してみます。ファイル名をhello.htmlとします。
1 |
|
アプリを起動して表示してみます。
1 | npm start |
ブラウザで以下のURLを開きます。
Hello!が表示されれば成功です。
Ctrl+cでアプリを終了します。
2.5 ルーティングを実装する
それでは動的なページに関して、実際にどのようにルーティングを実装するのか見ていきましょう。ルーティングは、URLのパスに対するハンドラfunctionという形で実装します。例えば http://localhost/users/ というURLに対するルーティングは、/users/ というパスと、それに対応するハンドラ function を対応させるように書きます。
2.6 ルーティングの実装方法
ルーティングの定義
1 | app.METHOD(PATH, HANDLER) |
- app : express のインスタンス
- METHOD : get/post など
- PATH : URLのパス部分
- HANDLER : パスが一致したときに実行されるfunction
ルーティングの実装方法には、app.jsに直接書く方法と、モジュール化する方法の2種類あります。
(1) app.jsに直接書く方法
1 | var express = require('express'); |
このようにapp.jsに直接ルーティングを書くことができるのですが、ルーティングが増えるにしたがって、app.jsのコードが肥大化してしまうという問題が起こります。そこで、次のようにルーティング機能をモジュール化する方法がサポートされています。
(2) モジュール化する方法
Express Routerという機能を使ってハンドラの部分を別ファイルに切り出すことができます。
Expressジェネレータが生成したスケルトンには、./routes/user.jsというファイルがあり、このような内容になっています。
1 | var express = require('express'); |
app.js側では、外出しにしたルータモジュール(users.js)をrequireしておき、リクエストURLの’/user’というパスに対応づけられています。
1 | var usersRouter = require('./routes/users'); |
2.7 ルーティングを追加してみる
./routes/user.jsを編集して、次のようなURLに対するルーティングを追加してみましょう。
http://localhost/users/123
Expressは、URLのパス部分のマッチング処理にPath-to-RegExpを使っており、ルーティングに正規表現を使うことができます。
https://www.npmjs.com/package/path-to-regexp
パターン | マッチング例 |
---|---|
‘/ab+cd’ | abcd、abbcd、abbbcd など |
‘/ab*cd’ | abcd、abxcd、abRABDOMcd、ab123cd など |
/a/ | ルート名に「a」が含まれるすべてのもの |
/.*fly$/ | butterfly、 dragonflyなど |
また、URL中の可変パラメータは、コロン記号を使って”/:userId”のように定義できます。
1 | /:userId |
捕捉された値はreq.paramsオブジェクトにセットされます。
1 | req.params: { "userId": "123" } |
それでは、./router/user.jsを開いて以下のようなハンドラを追加してみます。
1 | // |
このコードを、./router/user.jsに追加すると、user.js全体は以下のようになります。
1 | var express = require('express'); |
2.8 アプリを起動して確認する
1 | npm start |
プラウザで以下のURLにアクセスしてみましょう。
okと表示されれば成功です。
また、アプリの起動コマンド$ npm start
を実行したターミナルで、「ユーザーID123が指定されました」が表示されていれば、パラメータが正しく渡っています。
以上でチュートリアルの第1回は終わりです。
まとめ
ルーティングを追加
1 | router.get('/:userId', function(req, res, next) { |
確認URL