LoginSignup
10
13

More than 5 years have passed since last update.

Play frameworkことはじめ

Last updated at Posted at 2018-07-30

Play Framework

世の中には多様なウェブシステムのためのフレームワークがありますが、今回はPlayに注目して話します。Javaには伝統的にJavaEEというものがあり、最近はやりのkotlinでのコーディングが可能なSpringもかなり使いやすくなっていますが、scalaなどの親和性も考慮するとPlayが一番よさそうなため。アーキテクチャもモダンなので管理がしやすい印象です。

Playのインストール

以前はactivatorというツールがあったようですが、今は提供されていないようです。公式ドキュメントによると現在はGitHubからスターターコードをダウンロードするか、sbtのgilter8テンプレートを使うというのが推奨されている始め方のようです。gilter8を使う場合は以下のようにします。

 sbt new playframework/play-scala-seed.g8

該当フォルダに移動して、sbt runとするとhttp://localhost:9000にサンプルアプリが立ち上がります。まずはこれで準備は完了です。ちなみにこの状態でも、scalaに特有のauto-reload機能が有効なので、ソースコードを修正すると即座に再コンパイルされ、再スタートされます。便利ですね。ちなみにこれはtrigger executionという機能で、~をsbtコマンド前にいれると、どのコマンドでも実行できます。(~ compile, ~ run, ~ test, etc...)

IDEのセットアップ

上記のauto-reload機能があれば、特にIDEはいらないともいえますが、生産性を高めるために、EclipseやIntellij IDEAとの連携も考慮されています。ここではIntellij IDEAを使ってセットアップします。事前にIntellijのScala Pluginのインストールをしておきます。

sbtプロジェクトはIntellij IDEAで直接インポートすることができますので、先ほど作ったプロジェクトを読み込みます。新たなRun Configurationを作って、SBT Taskのrunを実行させるようにすれば、上記と同じ環境を再現できます。

Intellijで便利なのは、play.editorコンフィグレーションを使うことで、エラーページからのソースコードへのダイレクトリンクを実現できることです。IntellijではリモートファイルREST APIのための組み込みウェブサーバがポート63342で動いています。これに繋ぐ設定を、conf/application.confに記載します。

application.conf
play.editor="http://localhost:63342/api/file/?file=%s&line=%s"

加えて、build.sbtに以下の記述を追記します。

build.sbt
fork := true // required for "sbt run" to pick up javaOptions

javaOptions += "-Dplay.editor=http://localhost:63342/api/file/?file=%s&line=%s"

この他にもPLAY_EDITOR環境変数を定義することで実現することもできます。

PLAY_EDITOR="http://localhost:63342/api/file/?file=%s&line=%s"

ルーティングことはじめ

サンプルアプリケーションを起動すると、Playのチュートリアルが確認できます。
PlayはMVCのフレームワークに沿って構成されています。まず最初に理解すべきは、コントローラにウェブのリクエストをルーティングするルールの記載方法です。conf/routesという静的なファイルにルールを記載します。これはアプリケーションで記載するよりもわかりやすいと感じます。例えば以下のように記載します。

GET   /                    controllers.HomeController.index
GET   /clients/:id         controllers.Clients.show(id: Long)
GET   /files/*name          controllers.Application.download(name)

1番目の設定はhttp://localhost:9000直下のリクエストを、HomeControllerに定義されている関数であるindexにルーティングする設定です。2番目の設定は、Clientsに定義されている関数であるshowにルーティングするとともに、関数の引数にidを割り当てます。最後の設定はワイルドカードを使ったパターンで、立てばファイル名などimages/log.pngなどにもマッチします。他にも正規表現を使った柔軟なマッチングが可能です。この辺は公式ドキュメントが詳しいです。

コントローラ

ルーティングで定義されたコントローラはControllerを拡張したクラスになります。app/controllers以下に設置します。ControllerはAbstractControllerを拡張したクラスで、前の@Injectアノテーションも必須です。Play2.6以降に仕様が変わったようです。Action型を返す関数を定義する必要がありますが、testの中のOkという関数は実際にはplay.api.mvc.Resultを返します。Okはシンタックスシュガーなので、Resultをnewして返り値とすることも可能です。

app/controllers/TestControllers.scala
package controllers
import play.api._
import play.api.mvc._

class TestContoller @Inject() (cc: ControllerComponents) extends AbstractController(cc) {
    def test(String name) = Action {
        Ok("Hello " + name + "!");
    }
}

同じく、conf.routesに以下を追記します。localhost:9000/test/bobなどとすると、ブラウザにHello bob!と表示されます。

GET   /test/:name         controllers.TestContoller.test(name:String)

Viewの定義

PlayではTwirlというASP.NETのRazorにインスパイアされたテンプレートエンジンを使うのが一般的のようです。ファイルはapp/views以下に配置されます。@マークを使って、ダイナミックに値を埋め込む記法をとります。公式ドキュメントはこちら

先ほどのTestControllerを少し変えて、テンプレートエンジンを使うようにしてみます。

app/controllers/TestControllers.scala
package controllers
import play.api._
import play.api.mvc._

class TestContoller @Inject() (cc: ControllerComponents) extends AbstractController(cc) {
    def test(String name) = Action {
        Ok(views.html.test("Hello " + name + "!");
    }
}

app以下にtest.scala.htmlというファイルを用意します。ここに上記から呼び出されるViewsを定義しています。結果は先ほどとまったく同じですが、複数の引数を取って、scalaの構文でlist要素を列挙するといったことは簡単にできます。

app/test.scala.html
@(message: String)

<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>Test</title>
    </head>
    <body>
        @message
    </body>
</html>

おわりに

SpringやJavaEEなどに比べるとPlayが簡易で柔軟なフレームワークであることは、よく理解できます。まだまだ枯れておらず、仕様が細かいところで結構変わっているようなので、最新の公式ドキュメントを追わないといけないのが、ハードルが高くなっている気もしますが、一度覚えてしまえばよっぽど容易かなと感じる次第。次はLagomにも挑戦してみます。

10
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
13