§Play 2.0 の紹介
2007 年以来、私たちは Java での web アプリケーション の開発を容易なものにしようとしてきました。Play は、 Zenexity における内部的なプロジェクトとしてスタートし、私たちの web プロジェクトの進め方に強く影響されてきました。つまり、開発者の生産性に焦点を当て、 web のアーキテクチャを尊重し、初めからパッケージング規約に対して斬新なやり方を採用してきたのです - そうすることが理にかなっている場合には、いわゆる JEE のベストプラクティスをも破ってきました。
2009 年に、私たちはこれらのアイデアを、オープンソースプロジェクトとしてコミュニティと共有することを決断しました。即座に返されたフィードバックは極めてポジティブなものであり、このプロジェクトは大きな関心を引きつけました。今日 - 2 年間の活発な開発を経て - Play にはいくつかのバージョンができ、4,000 人の参加者からなる活発なコミュニティが存在し、世界中で実際に使われているアプリケーションの数は増え続けています。
世界中に対してプロジェクトを解放するということは、確かにより多くのフィードバックを得られるということではありますが、それはまた、新たなユースケースに出会ってそこから学ぶことや、新たな機能が必要になることや、 元々の設計や前提の下では考慮されていなかったバグが明らかになることでもあります。オープンソースプロジェクトとして Play に取り組んできた 2 年の間に、私たちはこういったすべての問題を修復し、加えて広範囲なシナリオをサポートするための新たな機能を統合してきました。 Play のプロジェクトが成長するにつれて、私たちは Play のコミュニティと、私たち自身の経験から学びました - Play は、どんどん複雑で、多様なプロジェクトで使われるようになってきたのです。
一方、技術と web の進化の歩みはとどまることを知りません。web は、あらゆるアプリケーションの中心となりました。 HTML, CSS, JavaScript の技術は、急速に発展してきましたーサーバーサイドのフレームワークがついていくことはほとんど不可能なほどです。web のアーキテクチャは、総体として、リアルタイム処理の方向へ急速に向かっており、今日のプロジェクト群に求められるようになった事項からは、データストア技術として SQL を唯一のものとするわけにはいかなくなっていることが分かります。プログラミング言語のレベルにおいては、私たちは、一般的になってきた Scala を含むいくつかの JVM 言語に関連する、後々まで記憶されるような変化の目撃者となりました。
それこそが、新時代の web フレームワーク、 Play 2.0 を開発した理由です。
§非同期プログラミングの構築
今日の web アプリケーションは、これまで以上にリアルタイムデータの並行処理を統合するようになってきており、 web フレームワークには完全な非同期 HTTP プログラミングモデルをサポートすることが求められます。 Play はまず、短期間に処理される大量のリクエストを処理する、クラシックな web アプリケーションを扱うように設計されました。しかし今日では、Comet、長期間のポーリング、WebSockets を通じて、接続が保持され続けるコネクションを処理するため、イベントモデルへと進むべきです。
Play 2.0 は、最初からすべてのリクエストが潜在的に長期間保持されるものと見なして設計されています。しかしそれだけではなく、私たちには、長時間にわたって処理されるタスクのスケジューリングと実行を扱う、強力な方法も必要です。 今日、並列度が非常に高いシステムを扱うモデルとしては、Actor ベースのモデルが最良であること、そして Java と Scala の双方で利用可能な Actor ベースのモデルの実装として、Akka が最良のものであることは、疑問の余地がありません - これが、Akka を使う理由です。Play 2.0 は Play アプリケーションで Akka をネイティブにサポートし、高度な分散システムを書くことができるようにします。
§型安全性へのフォーカス
Play のアプリケーションを書くための言語として 静的型付け言語を使う利点の一つは、コンパイラがコードのある部分をチェックできるという点にあります。これは、開発プロセスの早期にミスを検出するのに有効であるのみならず、多くの開発者が参加する大規模なプロジェクトでの作業をとても容易にしてくれます。
Play 2.0 の中に Scala を追加することで、私たちは間違いなく、コンパイラによるさらに強力な保障という利点を得ることになります - しかし、それでもまだ十分ではありません。Play 1.x では、テンプレートシステムは動的なものであり、 Groovy に基づくもので、コンパイラにできることはそれほどありませんでした。その結果、テンプレートで発生するエラーは、実行時にしか検出できなかったのです。これは、コントローラとの間を取り持つコードの検証についても同じことが言えました。
私たちは Play 2.0 において、コードのほとんどをコンパイル時にチェックさせるという考え方をさらに推し進めたいと強く考えています。そのため、私たちは Play のアプリケーションのデフォルトとして、 Scala ベースのテンプレートエンジンを使うことに決めました - これは、Java をメインのプログラミング言語として使う開発者にとっても、です。ただしだからといって、Play 1.x でテンプレートを書くために、Groovy を本当に知っていることが必要だったわけではないのと同様に、Scala のエキスパートにならなければ Play 2.0 でテンプレートを書くことができないということではありません。
Scala が主に使われるのは、Java のシンタックスに極めて近いシンタックスを使って、必要な情報を表示するのにオブジェクトグラフをたどっていくためです。とはいえ、Scala の持つパワーを生かして高度に抽象化されたテンプレートを書きたいなら、式指向で関数型である Scala が、どれほどテンプレートエンジンにぴったりなのかは、すぐに理解できることでしょう。
そして、これはテンプレートエンジンにだけ言えることではありません。ルーティングのシステムもまた、完全に型が検査されることになります。Play 2.0 は、ルートに関するすべての記述をチェックし、リバースルートの部分も含めて、すべてにおいて整合性が保たれているかどうかを検証します。
完全にコンパイルが行われることの嬉しい副作用として、テンプレートとルートファイルのパッケージ化と再利用が容易になることと、これらの部分の実行時のパフォーマンスの大幅な向上が見込めるということもあります。
§Java 及び Scala のネイティブサポート
Play 1.1 から、Play のアプリケーションを書くのにプログラミング言語 Scala を使用する可能性を、私たちは探り始めました。この作業は、まずフレームワークそのものに影響を与えることなく、自由に試せるような外部モジュールとして導入されました。
Scala を適切に Java ベースのフレームワークに統合することは容易なことではありません。Scala が持つ Java との互換性を考慮すれば、単純に Scala のシンタックスを Java のシンタックスの代わりに使う形で、まず単純に素早く統合してしまうことは可能です。しかしこれは間違いなく、Scala を利用する上で最適な方法ではありません。 Scala は、真のオブジェクト指向と関数型プログラミングを混合したものです。Scala の本当のパワーを解放するには、Play のフレームワークの API の多くを再検討しなければなりません。
今では、私たちは個別のモジュールとして Scala をサポートするやり方の限界点に到達しています。私たちが Play 1.x で行った、初期の設計における選択は、Java のリフレクションAPIとバイトコードの操作に強く依存しており、Play の内部の重要な部分のいくつかについて完全に再検討し直さなければ、これ以上の進歩は難しくなっていました。一方で、私たちは Scala モジュールのために、新たな型安全テンプレートエンジンや、まったく新しい SQL アクセスコンポーネントである Anorm といった、複数の素晴らしいコンポーネントを作成していました。そこで私たちは、 Scala の持つパワーを Play で完全に解放するために、Scala のサポートを個別のモジュールから、Play 2.0 のコアへ移すことを決断しました。この Play 2.0 のコアは、初めからプログラミング言語として Scala をネイティブにサポートするよう設計されることになります。
一方で、Java に対するサポートが Play 2.0 から弱くなることはまったくありません。むしろ、完全にその反対なのです。 Play 2.0 のビルドは、Java の開発者に対し、開発の体験を拡張する機会を提供します。
§強力なビルドシステム
私たちは初めから、Play のアプリケーションの実行、コンパイル、デプロイについて、斬新な方法を選択してきました。当初、私たちの採った方法は、難解な設計に見えたかも知れません - しかし、標準的な Servlet API の代わりに非同期 HTTP API を提供し、ライブコンパイルと開発中のソースコードのリロードによって短いフィードバックサイクルを提供し、斬新なパッケージングのアプローチを推進することは、極めて重要なことだったのです。その結果として、Play が標準的な JEE の規約に従うことは難しくなりました。
今日では、コンテナレスデプロイメントの概念は、Javaの世界において非常に広く受け入れられるようになってきました。この設計上の選択によって、Play framework は Heroku のようなプラットフォームにおいてネイティブに動作できるようになりました。私たちは、Heroku によって紹介されたモデルは、エラスティックな PaaS プラットフォームにおける Java アプリケーションのデプロイメントの未来だと考えています。
一方で、既存の Java のビルドシステムは、この新しいアプローチをサポートするには、柔軟性が不足していました。私たちは、Play のアプリケーションを実行し、デプロイするための単純明快なツールを提供したいと考えていたことから、Play 1.x では ビルドとデプロイメントのタスクのすべてを処理するために、Python スクリプトの集合体を作り上げました。
しかし、ビルドのプロセスのカスタマイズや、企業内の既存のビルドシステムとの統合が求められる、よりエンタープライズ規模のプロジェクトで Play を使っている開発者の方々は、少々困っていました。私たちが Play 1.x で提供していた Python のスクリプト群は、完全な機能を完備したビルドシステムではまったくありませんでしたし、カスタマイズも容易ではありませんでした。これが、私たちが Play 2.0 でさらに強力なビルドシステムへ舵を切ることを決めた理由です。
Play 独自の規約をサポートでき、Java と Scala のプロジェクトをビルドできるだけの柔軟性を持った、現代的なビルドツールが必要だったことから、私たちは SBT を Play 2.0 に統合することにしました。ただしこれによって、既存の Play のビルドのシンプルさに満足しているユーザーが脅かされることがあってはなりません。私たちは、拡張性のあるモデルの上で、これまで同様のシンプルな play new
, run
, start
が体験できるようにしようとしています。 Play 2.0 は、ほとんどのユーザーにとっては、とにかく単純にうまく処理をこなしてくれる、設定済みのビルドスクリプトを持つことになります。一方で、アプリケーションのビルドやデプロイの方法を変更する必要がある場合は、 Play のプロジェクトは標準的な SBT プロジェクトになるので、カスタマイズや特殊な要求への適用に応えるだけのあらゆるパワーを活用できるのです。
これはまた、Play 2.0 はインストール直後から、Maven との統合がこれまでよりもうまくできているということでもあり、プロジェクトをシンプルな jar ファイルの集合体としてパッケージ化し、任意のリポジトリへ公開できるということでもあり、さらには依存しているいかなる標準的な Java あるいは Scala ライブラリが開発中の状態であっても、ライブコンパイルやリローディングが可能だということでもあります。
§データストアとモデルの統合
データストアは、もはや「SQL データベース」の同義語ではありませんし、おそらくはこれまでもそうではありませんでした。データストアの興味深いモデルは、数多くのものが広く使われるようになり、様々なシナリオにおいて、様々な特徴が提供されてきました。そのため、Play のような web フレームワークにとっては、開発者がどのようなデータストアを利用するのか、明確な推測をすることが難しくなってきたのです。Play における汎用モデルの考え方は、単一の API でこういった技術のすべてを抽象化するのはほとんど不可能である以上、もはや意味を成さないものになってしまっています。
私たちは Play 2.0 で、どのようなデータストアドライバ、ORM あるいはその他のデータベースアクセスライブラリも、特にこのフレームワークに統合することなく、容易に利用できるようにしたいと考えています。私たちは単に、コネクションのバインドの管理のような、一般的な技術的課題を扱うための、最小限のヘルパーを提供するようにしたいのです。とはいえ、私たちはまた、特殊な要求を持たないユーザーがクラシックなデータベースへアクセスするためのデフォルトのツールをバンドルすることで、 Play フレームワークのフルスタックという性格も保ち続けたいと思っています。それこそが、 Play 2.0 が Ebean, JPA, Anorm といったビルドインのリレーショナルデータベースアクセスライブラリを同梱している理由です。
このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。