Documentation

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

§HTTPルーティング

§組み込み HTTP ルータ

ルータは、クライアントから受け取った HTTP リクエストをアクションへ変換するコンポーネントです。

HTTP リクエストは MVC フレームワークにとってイベントであるといえます。このイベントには大きく分けて次の二つの情報が含まれています。

ルートは conf/routes ファイルに定義しておくことでコンパイルされます。これは、ルート定義に関するエラーもブラウザで直接的に確認できるということです。

§routes ファイルの文法

conf/routes はルータによって読み込まれる設定ファイルです。このファイルには、アプリケーションが必要とする全てのルートをリストアップします。それぞれのルートは、HTTP メソッドと URI パターン、そしてその二つに割り当てられた Action ジェネレータの呼び出しで表します。

実際のルート定義を見てみましょう。

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

それぞれのルートでは、先頭に HTTP メソッド、その後に URI パターンが続きます。最後がアクション呼び出しの定義です。

# の文字を使って、routes ファイルにコメントを残すこともできます。

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

§HTTP メソッド

HTTP メソッドには、HTTP がサポートするあらゆるメソッド (GETPOSTPUTDELETEHEAD) が指定できます。

§URI パターン

URI パターンはルートのリクエストパスの定義です。リクエストパスの一部を動的にすることができます。

§静的パス

例えば、リクエストを GET /clients/all に完全一致させたいときは、次のように定義できます。

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

§動的パート

しかし、URL からクライアント ID を取得するような場合には、動的パートを追加する必要があります。

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

1 つの URI パターンには、2 つ以上の動的パートを含められます

動的パートのデフォルトのマッチ規則は正規表現でいうと [^/]+ です。したがって、:id という動的パートはちょうど一つの URI パートにマッチします。

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

動的パートを使って、URI パスの / で分割された複数のセグメントをまとめてキャプチャしたいときは、.* という正規表現に対応する *id という文法が使えます。

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

これで、GET /files/images/logo.png というリクエストに対して、動的パート nameimages/logo.png という値をキャプチャさせることができます。

§独自の正規表現による動的パート

動的パートに独自の正規表現を使わせたい場合は、$id<regex> という文法を利用します。

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

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

ルート定義の最後のパートは、アクションの呼び出しです。このパートでは、play.api.mvc.Action の値を返すメソッドへの呼び出しを定義する必要があります。通常は、コントローラのアクションメソッドの呼び出しになります。

メソッドが一つも引数を取らない場合、単にメソッドの完全修飾名を指定します。

GET   /                     controllers.Application.homePage()

アクションメソッドが引数を取る場合、全ての引数はリクエスト 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 型の引数の場合、型の記述はオプションです。リクエストパラメータを特定の Scala 型に変換したいときは、型を明示することができます。

GET   /client/: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)

§ルートの優先度

リクエストに複数のルートがマッチしてしまうことがあります。そのような競合が発生した場合は、先に宣言された方のルートが優先されます。

§リバースルーティング

Scala コード中で URL を生成するためにルータを使うこともできます。これにより、URI パターンの定義をただ一つの設定ファイルに集約することができ、アプリケーションをリファクタリングする際の間違いを減らすことができます。

ルータは、routes ファイルから利用された全てのコントローラについて、routes パッケージ以下に リバースコントローラ を生成します。リバースコントローラは元になったコントローラと同じシグネチャで、play.api.mvc.Result の代わりに play.api.mvc.Call を返すようなメソッドを持っています。

play.api.mvc.Call は HTTP 呼び出しを表していて、HTTP メソッドと URL の両方の情報を持っています。

例えば、次のようなコントローラを作成したとします。

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 というアクションメソッドの URL を逆引きすることができます。

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

次ページ: レスポンスの変更