Documentation

§HTTP ルーティング

§ビルトイン HTTP ルータ

ルータとは、送られてきた HTTP リクエストをそれぞれ対応するアクションの呼び出しに変換する役割を持つコンポーネントです。

HTTP リクエストは MVC フレームワークにとってはイベントであるといえます。このイベントには、次の 2 つの重要データが含まれています。

ルートは conf/routes ファイル内に定義され、コンパイルされます。したがって、ルート定義のエラーはブラウザ上ですぐ確認できます。

§依存性の注入

Play は 2 種類のルータ生成をサポートしていて、ひとつは依存性注入のルータ、もうひとつは静的なルータです。デフォルトは静的なルータですが、Activator のテンプレートを使用して新しい Play アプリケーションを作成した場合は、プロジェクトには依存性注入のルータが使用されるように build.sbt に次の設定が含まれます。

routesGenerator := InjectedRoutesGenerator

Play のドキュメントのコードサンプルは依存性注入のルートジェネレータを使用することを前提としています。これを使用しない場合は、ルートのコントローラの呼び出し部分の前に @ を付けるか、各コントローラを class ではなく object として宣言することで、静的なルートジェネレータ用のコードサンプルに作り変えることができます。

§ルートファイルの文法

conf/routes はルータによって利用される設定ファイルです。このファイルにはアプリケーションの全てのルートの一覧があります。各ルートは HTTP メソッドと URI パターン、そしてその 2 つが関連付けられた Action ジェネレータで構成されています。

ルート定義を例を見てみましょう。

GET   /clients/:id          controllers.Clients.show(id: Long)

各ルートの先頭は HTTP メソッドで、次が URI パターンです。最後の要素は呼び出し定義 (call definition) と呼ばれます。

# から始まるコメント行を書くこともできます。

# Display a client.
GET   /clients/:id          controllers.Clients.show(id: Long)

§HTTP メソッド

HTTP メソッドには HTTP がサポートする有効なメソッド (GET, POST, PUT, DELETE, HEAD) が全て使えます。

§URI パターン

URI パターンはルートのリクエストパスを定義します。リクエストパスの各パートはそれぞれ動的にマッチさせることができます。

§静的パス

例えば、 GET /clients/all へのリクエストだけをマッチさせたい場合、次のようなルートになります。

GET   /clients/all          controllers.Clients.list()

§動的パート

例えば、クライアント ID を受け取るようなルートを定義する場合、次のような動的パートを使うことができます。

GET   /clients/:id          controllers.Clients.show(id: Long)

一つの URI パターンには、複数の動的パートを含められます

動的パートをマッチングするデフォルトの方法は、[^/]+ という正規表現によって定義されています。これはすなわち、 :id のように定義した動的パートは、ちょうど一つの URI パートにマッチすることを意味します。

§複数の / をまたぐ動的パート

/ で区切られる URI パスセグメントを複数キャプチャする動的パートを定義したい場合、*id という文法を使って定義することができます。この文法は、正規表現 .+ を使います。

GET   /files/*name          controllers.Application.download(name)

GET /files/images/logo.png のようなリクエストについて、 name という動的パートは images/logo.png という値をキャプチャします。

§動的パーツに使う正規表現のカスタマイズ

動的パートに独自の正規表現を使うためには、$id<regex>という構文を使って次のような定義をします。

GET   /items/$id<[0-9]+>    controllers.Items.show(id: Long)

§アクションジェネレータメソッドの呼び出し

ルート定義の最後の部分は、アクションの呼び出しです。この部分には play.api.mvc.Action 型の値を返すようなメソッドの有効な呼び出しを書くことになっています。通常は、コントローラのアクションメソッドを呼び出すことになるでしょう。

メソッドに一つもパラメータが存在しない場合、単にメソッドの完全修飾名を書きます。

GET   /                     controllers.Application.homePage()

アクションメソッドにパラメータが存在する場合は、全てのパラメータがリクエスト URI から検索され、 URI パス部分かクエリストリングのいずれかから抽出されることになります。

# Extract the page parameter from the path.
GET   /:page                controllers.Application.show(page)

または

# Extract the page parameter from the query string.
GET   /                     controllers.Application.show(page)

上記のルートに対応する controllers.Application コントローラの show メソッドは次のとおりです。

def show(page: String) = Action {
  loadContentFromDatabase(page).map { htmlContent =>
    Ok(htmlContent).as("text/html")
  }.getOrElse(NotFound)
}

§パラメータの型

String 型のパラメータについては、型は指定しなくても構いません。しかし、送られてきたパラメータを Play に他の型へ変換させたい場合は、パラメータの型を明記する必要があります。

GET   /clients/:id          controllers.Clients.show(id: Long)

対応する controllers.Clients コントローラの show メソッドにも同様の型を定義します。

def show(id: Long) = Action {
  Client.findById(id).map { client =>
    Ok(views.html.Clients.display(client))
  }.getOrElse(NotFound)
}

§パラメータに固定値を渡す

パラメータに固定値を渡したい場合は、次のようにします。

# Extract the page parameter from the path, or fix the value for /
GET   /                     controllers.Application.show(page = "home")
GET   /:page                controllers.Application.show(page)

§パラメータにデフォルト値を設定する

送信されてきたリクエストに値が存在しない場合にデフォルト値を使うためには、次のようにします。

# Pagination links, like /clients?page=3
GET   /clients              controllers.Clients.list(page: Int ?= 1)

§省略可能なパラメータ

必ずしもリクエストに含まれていなくてもよい省略可能なパラメータを定義するためには、次のようにします。

# The version parameter is optional. E.g. /api/list-all?version=3.0
GET   /api/list-all         controllers.Api.list(version: Option[String])

§ルートの優先度

同じリクエストに複数のルートがマッチする可能性もあります。そのようなルートの競合が起こった場合、 (定義した順番が) 最初のルートが利用されます。

§リバースルーティング

ルータは Scala から呼び出して URL を生成させるという使い方もできます。これにより、全ての URI パターンを一つの設定ファイルに集約することができ、アプリケーションのリファクタリングをより安全に行うことができるようになります。

ルータはルートファイルで使われるそれぞれのコントローラについて routes パッケージ以下に「リバースコントローラ」を生成します。リバースコントローラにはコントローラと同じシグネチャを持つ、同名のアクションメソッド定義されていますが、それぞれ play.api.mvc.Action の代わりに play.api.mvc.Call を返すようになっています。

play.api.mvc.Call は HTTP 呼び出しを表していて、 HTTP メソッドと URI が両方とも含まれてます。

例えば、次のようなコントローラを作成した場合を考えてみます。

package controllers

import play.api._
import play.api.mvc._

class Application extends Controller {

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

}

そして、 conf/routes ファイルで次のようなマッピングを行ったとします。

# Hello action
GET   /hello/:name          controllers.Application.hello(name)

すると、 controllers.routes.Application リバースコントローラを利用することで、 hello アクションメソッドの URI を逆引きすることができます。

// Redirect to /hello/Bob
def helloBob = Action {
  Redirect(routes.Application.hello("Bob"))
}

Next: レスポンスの操作


このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。