Expressフレームワーク
サンプルの解説に入る前に、Expressフレームワークの構成、動作といった点について説明します。
Express構成
Express用テンプレートを展開した時点でのプロジェクト構造は、リスト3のとおりです。
C:\Node\sample\Webrole1 │ app.js (1) ├─public (2) │ ├─images │ ├─javascripts │ └─stylesheets │ style.css ├─routes (3) │ index.js └─views (4) index.ejs layout.ejs
(1)のapp.jsは初期のサーバー起動スクリプトです。(2)のpublicフォルダはJavascriptやスタイルシート、画像などコンテンツを保管します。(3)のroutesフォルダのindex.jsスクリプトには、リクエスト毎に振り分けられた処理を実装します。直接、app.jsに実装することもできます。(4)のviewsフォルダは、出力元となるテンプレートを格納します。各テンプレートは、layout.ejsの<body>タグの中に挿入されます。
Expressの内部動作
Expressは、いわゆるMVCフレームワークを採用しています。MVCとはモデル(Model)、ビュー(View)、コントローラー(Controller)を意味し、アプリケーションを構造的に作成するためのアーキテクチャです。このような構造にすることによってコンポーネント間の依存性を排除し、アプリケーション開発の分業性や保守性などを向上できます。それぞれの構成要素の概要は下表のとおりです。
構成要素 | 概要 |
モデル | ビューに表示されるオブジェクトモデルやロジックを表現 |
ビュー | ユーザーへの情報表示や入出力を受け持つ |
コントローラー | ユーザーからの入力を受け付け、モデルやビューを制御 |
これらの要素をExpressに当てはめた場合の概要が下図です。
それぞれの動きについて実際のコードを参照しながら確認していきましょう。
はじめにコントローラー部分から説明します。リスト4は、コントローラーに相当するapp.jsの抜粋です。コントローラーであるapp.jsは、ユーザーからのリクエストに応じて、モデルに処理を委譲します。
app.get('/', routes.index);
変数appはExpressサーバーのインスタンスが格納されています。以下の例では、Webサーバーのルート(例えば、http://localhost/)にアクセスがあった場合に、第2引数に指定されたroutes.index関数に処理を渡します。第2引数のメソッド名は、HTTPの動詞(Verb)に対応しています。ここはgetメソッドを使っていますが、他にもPUT/POST/DELETEなどに対応するput、post、deleteなどのメソッドが存在します。
このように、アクセスされたURLによって処理の振り分けを行うことをURLルーティングと呼びます。Expressにおけるコントローラー処理の多くは、アクセスされたURLによってどのような処理を実行するかを振り分けるための、URLルーティングの設定処理となります。
レンダリング部分(レスポンス処理)は、routes/index.jsに定義しますが、この部分もコントローラーの範疇と言えます(リスト5)。
exports.index = function(req, res){ res.render('index', { title: 'Express' }) };
res.renderメソッドによってテンプレートのレンダリングを行います。第1引数はテンプレート名、第2引数はテンプレートに渡す情報をJSON形式で指定します。
さてモデルですが、この例で言えばロジック的なものが無いため、第2引数に指定されたオブジェクトをモデルとみなすことができます。実際のアプリケーションでは複雑なオブジェクトモデルをロジックで組み立てていく部分がモデルにあたるでしょう。
最後にビュー部分です。ビューとして出力されるHTMLの雛形となるテンプレートはリスト6のように定義されます。
<h1><%= title %></h1> <p>Welcome to <%= title %></p>
テンプレートエンジンとしてEJSを指定したため、埋め込み式のJavascriptを記述できます。以下の例では、<%= title %>によってリスト5で渡された変数の展開を行っています。EJSの詳細な書式については、EJSのページを参照ください。
リスト5のindex.jsはルート要素のindex.ejsに対応しているわけではなく、Node.jsの仕様としてrequire('./routes')を実行したときに、暗黙的にindex.jsが読み込まれるためこのような名前付けになっています。今回のサンプルでは、レンダリング部分は、すべてindex.jsファイルに実装しています。またモデル(ロジック)についても、index.jsに実装しています。MVCやファイルの分割実装サンプルは、Expressのサンプルを参照ください。