Documentation

You are viewing the documentation for the 2.2.0 release in the 2.2.x series of releases. The latest stable release series is 2.4.x.

§HTTP ルーティング

§ビルトイン HTTP ルータ

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

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

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

§ルートファイルの文法

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._

object 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"))
}

次ページ: レスポンスの操作