主要な概念
MVC アプリケーションモデル
Play アプリケーションは web に適用された MVC アーキテクチャパターンに従います。
このパターンはアプリケーションを別々の層: Presentation 層 と Model 層 に分割します。Presentation 層 はさらに View 層 と Controller 層 に分けられます。
- Model は、アプリケーションが扱う情報をドメインに特化して表現したものです。ドメインのロジックは生のデータに ‘意味’ (例えば、今日がユーザの誕生日かとか、あるいはショッピングカートの合計や税金や送料などを計算して) を追加します。ほとんどのアプリケーションが、データを保存するためにデータベースなどの永続的なストレージを使用します。Model によって隠蔽されるかカプセル化されることが分かっているので、MVC ではデータアクセス層について明確には言及しません。
- View は、通常はユーザインタフェースである双方向のやり取りに適した形式にモデルをレンダリングします。異なる目的に応じて、ひとつのモデルに対して複数のビューが存在することもあります。Web アプリケーションでは、通常、ビューは HTML、XML または JSON のような ‘Web フォーマット’ としてレンダリングされます。しかし、例えば動的にレンダリングされたチャートダイヤグラムのようにバイナリ形式としてビューを表現する場合もいくつかあります。
- Controller は、イベント (通常はユーザのアクション) に反応してそれらを処理します。このとき、モデルの変更も実行するかもしれません。Web アプリケーションでは、通常、イベントは HTTP リクエストです: コントローラは HTTP リクエストを待ち受けて、‘イベント’ からクエリ文字列パラメータやリクエストヘッダ… と言った関連データを抽出します。そして、下層のモデルオブジェクトに変更を適用します。
Play アプリケーションでは、これらの 3 つの層は app ディレクトリの中に、それぞれ別々の Java パッケージとして定義されます。
app/controllers
コントローラは、public かつ static なメソッドはいずれも action となるクラスです。アクションは HTTP リクエストが受信されたときに起動される Java のエントリポイントです。コントローラクラスの Java コードはまったくオブジェクト指向的ではありません: 主に手続き型のコードです。アクションメソッドは、HTTP リクエストから関連データを抽出して、モデルを検索するか更新して、HTTP レスポンスにラップされた結果を返します。
app/models
ドメインモデルオブジェクト層は、Java 言語から利用可能なすべてのオブジェクト指向特徴を使用する Java クラスの集合です。ドメインモデルオブジェクト層はアプリケーションが扱うデータ構造と操作を含んでいます。モデルオブジェクトを永続的なストレージに保存する必要がある場合は、ドメインモデルオブジェクト層には JPA アノテーションや SQL ステートメントのような、接着剤的な部品を含むこともあるかもしれません。
app/views
アプリケーションのビューのほとんどは、Play によって提供された効率的なテンプレートシステムを使用して生成されます。コントローラは、モデル層からいくつかのデータを取得し、これらのオブジェクトを装飾するためにテンプレートを適用します。このパッケージは HTML、XML、JSON やその他の、動的にモデルの値を表現する特別なディレクティブを持つテンプレートファイルを保持します。
リクエストライフサイクル
Play フレームワークは完全にステートレスであり、リクエスト/レスポンスのみを重視します。すべての HTTP リクエストは同じ処理フローを通ります:
- HTTP リクエストがフレームワークによって受信されます。
- Router コンポーネントは、このリクエストに適合する最も特殊なルーティングを探します。そして、対応するアクションメソッドが起動されます。
- アプリケーションコードが実行されます。
- 複雑なビューを生成する必要がある場合は、テンプレートファイルがレンダリングされます。
- アクションメソッドの結果 (HTTP レスポンスコードと内容) は HTTP レスポンスとして出力されます。
HTTP リクエストの処理フローを下図にまとめます:
標準的なアプリケーションレイアウト
Play アプリケーションのレイアウトは、できるだけ物事を簡単に保つために標準化されています。
app ディレクトリ
このディレクトリはすべての実行可能な部品: Java ソースコードとビューテンプレートを含みます。
.classファイルはどこ?
コンパイルされた Java クラスを探さないでください。フレームワークは実行時に Java ソースコードをコンパイルして、 tmp ディレクトリ配下にバイトコードキャッシュとしてコンパイルされたクラスを保持するだけです。Play アプリケーションにおける主な実行可能な成果物は、コンパイルされたクラスではなく、 .java ソースファイルです。
app ディレクトリには、MVC アーキテクチャパターンのそれぞれの層にあたる 3 つの標準的なパッケージがあります。もちろん、例えば utils のような独自のパッケージを追加することも可能です。
加えて、view パッケージの内容は複数のサブパッケージに整理されます:
- tags ディレクトリは、例えば再利用できるテンプレート部品のようなアプリケーションタグを管理します。
- コントローラごとにひとつのビューディレクトリ が割り当てられます。慣例により、コントローラに関連するテンプレートはそれぞれのサブパッケージ内に保持されます。
public ディレクトリ
public ディレクトリに保存されたリソースは、静的な資産であり、Web サーバによって直接配信されます。
このディレクトリは 3 つの標準的なサブディレクトリ: 画像、CSS スタイルシート、および JavaScript ファイル用のディレクトリに分けられます。すべての Play アプリケーションにおいて一貫性を保つために、静的な資産はこのように管理されるべきです。
Tip
デフォルトでは /public ディレクトリは /public という URL にマッピングされますが、これは容易に変更可能であり、静的な資産のために複数のディレクトリを使用することもできます。
conf ディレクトリ
conf ディレクトリはアプリケーションのためのすべての構成ファイルを含んでいます。
2 つの必要な構成ファイルがあります:
- application.conf は、アプリケーションのための主な構成ファイルです。標準的な構成オプションを含んでいます。
- routes は、ルーティングを定義するファイルです。
Tip
アプリケーションに特定のいくつかの設定オプションを加える必要がある場合、application.conf ファイルにさらにオプションを追加するのは良い案です。何かのライブラリが特定の設定ファイルを必要とするならば、conf ディレクトリ配下にそのファイルを格納するようにしてください: このディレクトリは Java クラスパスに含まれます 。
lib ディレクトリ
このディレクトリはアプリケーションに必要なすべての標準的な Java ライブラリを含みます。これらのライブラリは、自動的に Java クラスパスに追加されます。
開発ライフサイクル
Play を使って作業している間、コンパイル、パッケージング、そしてデプロイのいずれのフェーズも存在しません。一方で、Play には 2 つの異なった環境が用意されています: 開発フェーズ中の DEV モードと、アプリケーションがデプロイされるときの PROD モードです。
DEV/PROD モードについて
アプリケーションは DEV か PROD いずれかのモードで実行できます。 application.mode 設定プロパティを使ってこのモードを切り換えます。DEV モードで動作している場合、Play はファイルの変更をチェックし、必要な場合は動的にリロードします。
PROD モードは本番稼動向けに完全に最適化されます: Java ソースとテンプレートは、一度だけコンパイルされ、複数の用途のためにキャッシュされます。
Java ソースコードは、実行時にコンパイルされ、ロードされます。アプリケーションが動作している間に Java ソースファイルが変更された場合、ソースコードは再コンパイルされて JVM 上に動的にリロードされます。
コンパイルエラーが発生した場合、問題が正確にブラウザに表示されます (DEV モードの場合のみ) 。
テンプレートも動的に再コンパイルされ、リロードされます。
Java デバッガへの接続
アプリケーションを DEV モードで実行している場合、Java デバッガをポート 8000 に接続することができます。
例えば、NetBeans デバッガはこのように使用します:
考察を続けます
ここまでは、Play アプリケーションがどういったものであるかを見てきたので、 HTTP ルーティング がどのように動作するかを見ていきましょう。Router は送り込まれた HTTP リクエストのアクションへの対応付けを担当します。