ドキュメント

§HTTPルーティング

§組み込みHTTPルーター

ルーターは、各着信HTTPリクエストをアクション呼び出し(コントローラークラスのパブリックメソッド)に変換するコンポーネントです。

HTTPリクエストは、MVCフレームワークによってイベントとして認識されます。このイベントには、2つの主要な情報が含まれています。

ルートは、コンパイルされるconf/routesファイルで定義されます。つまり、ルートエラーはブラウザで直接確認できます。

§依存性注入

Playのデフォルトのルートジェネレーターは、@Injectアノテーション付きのコンストラクターでコントローラーインスタンスを受け入れるルータークラスを作成します。つまり、このクラスは依存性注入での使用に適しており、コンストラクターを使用して手動でインスタンス化することもできます。

Play 2.7.0より前は、Playはアクションをstaticメソッドとして定義することをサポートする静的ルートジェネレーターをサポートしていました。Playは静的状態に依存しなくなったため、これはサポートされなくなりました。独自の静的状態を使用したい場合は、インスタンスメソッドを使用してコントローラーで引き続き使用できます。

§ルートファイルの構文

conf/routesは、ルーターが使用する構成ファイルです。このファイルには、アプリケーションに必要なすべてのルートがリストされています。各ルートは、HTTPメソッドとURIパターンで構成され、アクションメソッドの呼び出しに関連付けられています。

ルート定義がどのようなものかを見てみましょう

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

注:アクション呼び出しでは、パラメータ型はScalaのようにパラメータ名の後に来ます。

各ルートはHTTPメソッドで始まり、その後にURIパターンが続きます。ルートの最後の要素は呼び出し定義です。

#文字を使用して、ルートファイルにコメントを追加することもできます。

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

+で始まる行でルートを先行することにより、修飾子を適用することもできます。これにより、特定のPlayコンポーネントの動作を変更できます。そのような修飾子の1つは、CSRFフィルターをバイパスする「nocsrf」修飾子です。

+ nocsrf
POST  /api/new              controllers.Api.newThing()

§HTTPメソッド

HTTPメソッドには、HTTP(GETPATCHPOSTPUTDELETEHEADOPTIONS)でサポートされている有効なメソッドのいずれかを使用できます。

§URIパターン

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

§静的パス

たとえば、GET /clients/allの着信リクエストを正確に一致させるには、このルートを定義できます

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

§動的部分

たとえば、IDでクライアントを取得するルートを定義する場合は、動的部分を追加する必要があります

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

注:URIパターンには、複数の動的部分を含めることができます。

動的部分のデフォルトのマッチング戦略は、正規表現[^/]+によって定義されます。これは、:idとして定義された動的部分が1つのURIパスセグメントと正確に一致することを意味します。他のパターンタイプとは異なり、パスセグメントは、コントローラーに渡される前にルートで自動的にURIデコードされ、逆ルートでエンコードされます。

§複数の/にまたがる動的部分

動的部分で、フォワードスラッシュで区切られた複数のURIパスセグメントをキャプチャする場合は、*id構文(.*正規表現を使用するワイルドカードパターンとも呼ばれる)を使用して動的部分を定義できます。

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

ここで、GET /files/images/logo.pngのようなリクエストの場合、nameの動的部分はimages/logo.pngの値をキャプチャします。

複数の/にまたがる動的部分は、ルーターによってデコードされず、逆ルーターによってエンコードされないことに注意してください。ユーザー入力と同じように、未加工のURIセグメントを検証するのはあなたの責任です。逆ルーターは単に文字列連結を実行するため、結果のパスが有効であり、たとえば、複数の先頭のスラッシュまたは非ASCII文字が含まれていないことを確認する必要があります。

§カスタム正規表現を使用した動的部分

$id<regex>構文を使用して、動的部分に独自の正規表現を定義することもできます。

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

ワイルドカードルートと同様に、パラメータはルーターによってデコードされず、逆ルーターによってエンコードされません。そのコンテキストで意味があることを確認するために、入力を検証するのはあなたの責任です。

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

ルート定義の最後の部分は、呼び出しです。この部分では、アクションメソッドへの有効な呼び出しを定義する必要があります。

メソッドがパラメータを定義しない場合は、完全修飾メソッド名のみを指定します

GET   /                     controllers.Application.homePage()

アクションメソッドがパラメータを定義する場合、対応するパラメータ値は、URIパス自体から抽出されるか、クエリ文字列から抽出されるかのいずれかで、リクエスト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);
  return ok(content).as("text/html");
}

§パラメータ型

String型のパラメータの場合、パラメータ型はオプションです。Playに着信パラメータを特定の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の場合と同様に、ジェネリック型は<>ではなく[]記号を使用して指定されます。たとえば、List[String]はJavaの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)
# or
GET   /api/list-all         controllers.Api.listOpt(version: java.util.Optional[String])

§リストパラメータ

繰り返しクエリ文字列パラメータのリストパラメータを指定することもできます。

# The item parameter is a list.
# E.g. /api/list-items?item=red&item=new&item=slippers
GET   /api/list-items      controllers.Api.listItems(item: java.util.List[String])
# or
# E.g. /api/list-int-items?item=1&item=42
GET   /api/list-int-items  controllers.Api.listIntItems(item: java.util.List[Integer])

§現在リクエストをアクションメソッドに渡す

現在リクエストをアクションメソッドに渡すこともできます。パラメータとして追加するだけです

GET   /                     controllers.Application.dashboard(request: Request)

および対応するアクションメソッド

public Result dashboard(Http.Request request) {
  return ok("Hello, your request path " + request.path());
}

Playは、型Request(これはplay.mvc.Http.Requestのインポート)のルートパラメータを自動的に検出し、実際のリクエストを対応するアクションメソッドのパラメータに渡します。もちろん、Requestパラメータを他のパラメータと混在させることができ、Requestパラメータがどの位置にあるかは関係ありません。

§ルーティングの優先度

多くのルートが同じリクエストに一致する可能性があります。競合がある場合、最初(宣言順)のルートが使用されます。

§逆ルーティング

ルーターは、Java の呼び出し内から URL を生成するために使用できます。これにより、すべての URI パターンを単一の設定ファイルに集中させることができるため、アプリケーションのリファクタリング時に自信を持つことができます。

routes ファイルで使用される各コントローラーに対して、ルーターは routes パッケージ内に「リバースコントローラー」を生成します。これには、同じシグネチャを持つ同じアクションメソッドがありますが、play.mvc.Result ではなく play.mvc.Call を返します。

play.mvc.Call は HTTP 呼び出しを定義し、HTTP メソッドと URI の両方を提供します。

たとえば、次のようなコントローラーを作成した場合

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.Application.hello アクションは、controllers.routes.Application.hello を介してリバースできます(routes ファイル内で、生成されたパスに一致する他のルートがない場合に限ります)。

リバースアクションメソッドは非常にシンプルに動作します。パラメーターを受け取り、それらをルートパターンに代入します。パスセグメント(:foo)の場合、値は代入される前にエンコードされます。正規表現とワイルドカードパターンの場合、値は複数のセグメントにまたがる可能性があるため、文字列は未加工の形式で代入されます。リバースルートに渡す際は、必要に応じてこれらのコンポーネントをエスケープし、検証されていないユーザー入力を渡さないようにしてください。

§相対ルート

絶対ルートの代わりに相対ルートを返すことが便利な場合があります。play.mvc.Call によって返されるルートは常に絶対(先頭が /)であり、HTTP プロキシ、ロードバランサー、API ゲートウェイによって Web アプリケーションへのリクエストが書き換えられると問題が発生する可能性があります。相対ルートを使用すると便利な例には、次のようなものがあります。

相対ルートを生成できるようにするには、ターゲットルートを相対にする対象(開始ルート)を認識する必要があります。開始ルートは現在の RequestHeader から取得できます。したがって、相対ルートを生成するには、現在の RequestHeader または開始ルートを String パラメーターとして渡す必要があります。

たとえば、次のようなコントローラーエンドポイントがある場合

package controllers;

import play.*;
import play.mvc.*;

public class Relative extends Controller {

  public Result helloview(Http.Request request) {
        ok(views.html.hello.render("Bob", request));
  }

  public Result hello(String name) {
    return ok("Hello " + name + "!");
  }
}

そして、それを conf/routes ファイルにマッピングした場合

GET     /foo/bar/hello              controllers.Relative.helloview(request: Request)
GET     /hello/:name                controllers.Relative.hello(name)

リバースルーターを使用して以前と同様に相対ルートを定義し、relativeTo(play.mvc.RequestHeader requestHeader) への追加呼び出しを含めることができます。

@(name: String, request: Http.RequestHeader)

<h1>Hello @name</h1>

<a href="@routes.Relative.hello(name)">Absolute Link</a>
<a href="@routes.Relative.hello(name).relativeTo(request)">Relative Link</a>

注: コントローラーから渡された Http.Request は、ビューパラメーターで Http.RequestHeader にキャストされます。

/foo/bar/hello をリクエストすると、生成された HTML は次のようになります

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Bob</title>
    </head>
    <body>
      <a href="/hello/Bob">Absolute Link</a>
      <a href="../../hello/Bob">Relative Link</a>
    </body>
</html>

§デフォルトコントローラー

Play には、いくつかの便利なアクションを提供する Default コントローラーが含まれています。これらは routes ファイルから直接呼び出すことができます。

# Redirects to https://play.dokyumento.jp/ with 303 See Other
GET   /about      controllers.Default.redirect(to = "https://play.dokyumento.jp/")

# Responds with 404 Not Found
GET   /orders     controllers.Default.notFound

# Responds with 500 Internal Server Error
GET   /clients    controllers.Default.error

# Responds with 501 Not Implemented
GET   /posts      controllers.Default.todo

この例では、GET / は外部 Web サイトにリダイレクトしますが、別のアクション(上記の例の /posts など)にリダイレクトすることも可能です。

§高度なルーティング

ルーティング DSLを参照してください。

次: HTTP 結果の操作


このドキュメントにエラーを見つけましたか?このページのソースコードは、こちらにあります。ドキュメントガイドラインを読んだ後、プルリクエストを遠慮なく送信してください。質問や共有するアドバイスがありますか?コミュニティフォーラムにアクセスして、コミュニティとの会話を始めてください。