§HTTPルーティング
§組み込み HTTP ルータ
ルータはクライアントから受け取った HTTP リクエストをアクション (コントローラクラス内の public なメソッド) の呼び出しへ変換するコンポーネントです。
HTTP リクエストは MVC フレームワークにとってイベントであるといえます。このイベントには大きく分けて次の二つの情報が含まれています。
- クエリストリングを含むリクエストパス (例えば、
/clients/1542
や/photos/list
) - HTTP メソッド (GET、POST など)
ルートは conf/routes
ファイルに定義しておくことでコンパイルされます。これは、ルート定義に関するエラーもブラウザで直接的に確認できるということです。
§依存性の注入
Play は、2 種類のルータ生成をサポートしています。1 つは依存性が注入されたルータ、もう 1 つは静的なルータです。デフォルトは静的ルータですが、もし Play seed Activator テンプレートを使用して新しい Play アプリケーションを作成した場合、プロジェクトには、注入されたルータを使用するように指示するため build.sbt
に以下の設定が含まれます。
routesGenerator := InjectedRoutesGenerator
Play のドキュメントにあるコードサンプルは、注入されたルータ生成を使用することを前提としています。もしこれを使用しない場合は、コントローラの呼び出し部分の前に @
シンボルを付けるか、それぞれのアクションメソッドを static
として宣言することで、静的なルータ生成用のコードサンプルに作り変えることができます。
§routesファイルの文法
conf/routes
はルータによって読み込まれる設定ファイルです。このファイルには、アプリケーションが必要とする全てのルートをリストアップします。それぞれのルートは、HTTP メソッドと URI パターン、そしてそれらに割り当てられたアクションメソッドの呼び出しで表します。
実際のルート定義を見てみましょう。
GET /clients/:id controllers.Clients.show(id: Long)
アクション呼び出しでは、Scala のように引数名の後に型を指定する事に注意して下さい。
それぞれのルートでは、先頭に HTTP メソッド、その後に URI パターンが続きます。最後がアクション呼び出しの定義です。
#
の文字を使って、routes ファイルにコメントを残すこともできます。
# Display a client.
GET /clients/:id controllers.Clients.show(id: Long)
§HTTPメソッド
HTTP メソッドには、HTTP がサポートするあらゆるメソッド (GET
、PATCH
、POST
、PUT
、DELETE
、HEAD
) が指定できます。
§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
というリクエストに対して、動的パート name
に images/logo.png
という値をキャプチャさせることができます。
§動的パートで独自の正規表現を使う
動的パートに独自の正規表現を使わせたい場合は、$id<regex>
という文法を利用します。
GET /items/$id<[0-9]+> controllers.Items.show(id: Long)
§アクションジェネレータメソッドの呼び出し
ルート定義の最後のパートは、アクションの呼び出しです。このパートでは、アクションメソッド呼び出しを定義する必要があります。
メソッドが一つも引数を取らない場合、単にメソッドの完全修飾名を指定します。
GET / controllers.Application.homePage()
アクションメソッドが引数を取る場合、対応する引数はリクエスト URI のパスまたはクエリストリングから抽出されます。
# Extract the page parameter from the path.
# i.e. http://myserver.com/index
GET /:page controllers.Application.show(page)
また、クエリストリングから抽出するためには、
# Extract the page parameter from the query string.
# i.e. http://myserver.com/?page=index
GET / controllers.Application.show(page)
このルートに対応する controllers.Application
コントローラの show
メソッドの定義は次のようになります。
public Result show(String page) {
String content = Page.getContentOf(page);
response().setContentType("text/html");
return ok(content);
}
§引数の型
String
型の引数の場合、型の記述はオプションです。リクエストパラメータを特定の Scala 型に変換したいときは、明示的に型を追記することができます。
GET /clients/:id controllers.Clients.show(id: Long)
このルートに対応するコントローラのアクションメソッドの引数には同じ型を使用します。
public Result show(Long id) {
Client client = clientService.findById(id);
return ok(views.html.Client.show(client));
}
ノート: 引数の型は後置形式で指定されます。また、ジェネリックスの型は Java の
<>
構文の代わりに[]
で指定されます。例えば、 Java でのList<String>
はList[String]
になります。
§引数に定数を渡す
アクションメソッドの引数に定数を渡したいときは、次のように記述します。
# 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 ?= null)
§ルートの優先度
リクエストに複数のルートがマッチしてしまうことがあります。そのような競合が発生した場合は、先に宣言された方のルートが優先されます。
§リバースルーティング
Java コード中で URL を生成するためにルータを使うことができます。これにより、URI パターンの定義をただ一つの設定ファイルに集約することができ、アプリケーションをリファクタリングする際の間違いを減らすことができます。
ルータは、routes ファイルから利用された全てのコントローラについて、routes
パッケージ以下に リバースコントローラ
を生成します。リバースコントローラは元になったコントローラと同じシグネチャで、play.mvc.Result
の代わりに play.mvc.Call
を返すようなメソッドを持っています。
play.mvc.Call
は HTTP 呼び出しを表していて、HTTP メソッドと URL の両方の情報を持っています。
例えば、次のようなコントローラを作成したとします。
package controllers;
import play.*;
import play.mvc.*;
public class Application extends Controller {
public Result hello(String name) {
return ok("Hello " + name + "!");
}
}
そして、このコントローラを conf/routes
で次のようにマッピングしたとします。
# Hello action
GET /hello/:name controllers.Application.hello(name)
このとき、controllers.routes.Application
というリバースコントローラを利用することで、hello
というアクションメソッドの URL を逆引きすることができます。
// Redirect to /hello/Bob
public Result index() {
return redirect(controllers.routes.Application.hello("Bob"));
}
注: 各コントローラパッケージには
routes
サブパッケージが存在します。このため、controllers.admin.Application.hello
アクションはcontrollers.admin.routes.Application.hello
によってリバースすることができます。
Next: HTTP レスポンスの操作
このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。