@tako_programingの忘備録とか

男子高校生の日常の忘備録

playのActions, Controllers and Resultsをてきとうに和訳

実はplayロクに触ったことがないので、ちゃんと勉強してみようかなぁという試みです。


Actionって?

playアプリケーションの受け取るほとんどのリクエストは、Actionによって処理されます。play.api.mvc.Actionは、基本的にリクエストを処理し、クライアントに送信する結果を生成する(play.api.mvc.Request => play.api.mvc.Result)型の関数です。

def echo = Action { request =>
  Ok("Got request [" + request + "]")
}

Actionは、Webクライアントに送信するHTTPレスポンスを表すplay.api.mvc.Result値を返します。この例では、Okはtext/plainを含む200 Okレスポンスを生成します。

Actionの生成

play.api.mvc.Actionコンパニオンオブジェクトは、Action値を構築するためのヘルパーメソッドをいくつか提供します。

まず最初に紹介するのは、引数として、Resultを返す式ブロックを取ります。

Action {
  Ok("Hello world")
}

これはActionを作成する最も簡単な方法ですが、受け取ったrequestへの参照がありません。このActionを呼び出すHTTPリクエストにアクセスすると便利なことがよくあります。 そのため、引数としてRequest => Resultをとる別のActionビルダーが存在します。

Action { request =>
  Ok("Got request [" + request + "]")
}

implicitキーワードを用いて、リクエストパラメータを暗黙的にマークすると、それを必要とする他のAPIによって暗黙的に使用されることがあります。

Action { implicit request =>
  Ok("Got request [" + request + "]")
}

最後に紹介するActionビルダーは、追加のBodyParserを指定するものです。

Action(parse.json) { implicit request =>
  Ok("Got request [" + request + "]")
}

BodyParserについての詳細はこのマニュアルの後半で説明します。今のところ、Action値を作成する他のメソッドはデフォルトのAny contetn body parserを使用していることを知っておいてください。

ControllerはActionを生成するオブジェクトです。

ControllerはAction値を生成するオブジェクトにすぎません。Controllerは、Dpendency Injenctionを利用するクラスとして定義することも、オブジェクトとして利用することもできます。 注:Controllerをobjectとして定義することは、playでは将来的にサポートされなくなります。クラスでのControllerの使用が推奨されます。 Action値のジェネレータを定義する最も簡単な方法は、Action値を返す、引数を持たないメソッドです。

package controllers

import play.api.mvc._

class Application extends Controller {

  def index = Action {
    Ok("It works!")
  }

}

もちろん、Actionジェネレータメソッドは引数を持つことも可能であり、これらの引数はクロージャとして使うことができます。

def hello(name: String) = Action {
  Ok("Hello " + name)
}

シンプルなresults

いまのところ私達は、ステータスコードなどのHTTPレスポンス、HTTPヘッダーのセット、およびWebクライアントに送信される文章などのシンプルな結果に興味があります。これらのシンプルな結果はplay.api.mvc.Resultによって定義されています。

import play.api.http.HttpEntity

def index = Action {
  Result(
    header = ResponseHeader(200, Map.empty),
    body = HttpEntity.Strict(ByteString("Hello world!"), Some("text/plain"))
  )
}

もちろん、上記のサンプルでOkのResultのような一般的な結果を作成するためのヘルパーがいくつか存在します。

さまざまな結果を表示するためのいくつかの例を下に示します。

val ok = Ok("Hello world!")
val notFound = NotFound
val pageNotFound = NotFound(<h1>Page not found</h1>)
val badRequest = BadRequest(views.html.form(formWithErrors))
val oops = InternalServerError("Oops")
val anyStatus = Status(488)("Strange response type")

なお、これらのヘルパーはすべてplay.api.mvc.Resultsのトレイトとコンパニオンオブジェクトに定義されています。

リダイレクトもシンプルなresultsです。

ブラウザを新しいURLにリダイレクトすることは、種類のことなるシンプルなresultsに過ぎません。ただ、これらの結果はリクエストボディを使用しません。 リダイレクトのためのResultを作成するには、いくつかのヘルパーが利用できます。

def index = Action {
  Redirect("/user/home")
}

標準のままだと、303 SEE_OTHERレスポンスタイプを使用しますが、必要に応じてより具体的なステータスコードを設定することができます。

def index = Action {
  Redirect("/user/home", MOVED_PERMANENTLY)
}

TODO ダミーページ

TODOとして定義された空のAction実装を使用することが可能です。そのresultは標準のNot implemented yetのページになります。

def index(name:String) = TODO