§コンテンツネゴシエーション
コンテンツネゴシエーションとは、同一のリソース (URI) を複数のフォーマットで提供するためのメカニズムです。用途としては、*例えば*複数の出力フォーマット (XML, JSON など) をサポートするような Web サービスを実装する場合です。サーバ駆動のネゴシエーションは Accept* リクエストヘッダの内容に基いて行われます。コンテンツネゴシエーションについての詳細は HTTP の仕様 を参照してください。
§言語
play.api.mvc.RequestHeader#acceptLanguages メソッドを呼び出すと、リクエストの Accept-Language ヘッダから、クライアント側で受付可能な言語のリストを取り出すことができます。リストは quality 値によってソートされます。Play は play.api.mvc.Controller#lang メソッド内でこのメソッドを呼び出して、 implicit な play.api.i18n.Lang 値をアクションのスコープ内に提供しています。これによって、アクション内では常に最適な言語 (クライアントが希望している言語をあなたのアプリケーションがサポートしている場合はそれを、そうでなければアプリケーションのデフォルト言語が代わりに提供されます) を利用することができます。
§コンテンツ
同様に、 play.api.mvc.RequestHeader#acceptedTypes メソッドを呼び出すことで、リクエストの Accept ヘッダから、クライアント側で受付可能な MIME タイプのリストを取り出すことができます。リストは quality 値でソートされます。
実際に Accept ヘッダに含まれているのは MIME タイプではなく メディアレンジ (*例えば* 任意のテキストを受け入れる場合は text/* というレンジ、ありとあらゆる結果を受け入れる場合は */* というレンジ) です。コントローラは高級な render メソッドを提供することで、これらメディアレンジの処理を補助してくれます。例として、次のアクション定義を見てください。
val list = Action { implicit request =>
val items = Item.findAll
render {
case Accepts.Html() => Ok(views.html.list(items))
case Accepts.Json() => Ok(Json.toJson(items))
}
}
Accepts.Html() および Accepts.Json() は、それぞれメディアレンジが text/html や application/json にマッチするかをテストする抽出子です。 render メソッドは play.api.http.MediaRange を入力に play.api.mvc.Result を返す PartialFunction を引数にとり、リクエストの Accept ヘッダ内のメディアレンジに優先度順に適用します。その PartialFunction で受け入れ可能なメディアレンジが一つも存在しない場合、 NotAcceptable という結果が返ります。
例えば、任意の型の結果を受け入れるが、 JSON を優先する、という意味である */*;q=0.5,application/json という Accept ヘッダを持つリクエストをクライアントが送信したとします。この場合、前述のコードは JSON 形式の結果を返します。一方、XML のみ受け付けるという意味である Accept ヘッダ application/xml を含むリクエストを他のクライアントが送信したとすると、 NotAcceptable を返します。
§リクエスト抽出子
play.api.mvc.AcceptExtractors.Accepts オブジェクトの API ドキュメントには、 Play が始めからから render メソッドでサポートしている MIME タイプの一覧が掲載されています。さらに、 play.api.mvc.Accepting ケースクラスを使うと、任意の MIME タイプに対応する独自の抽出子を実装することができます。例えば、メディアレンジが audo/mp3 MIME タイプにマッチするかどうかをチェックする抽出子は、次のように定義します。
val AcceptsMp3 = Accepting("audio/mp3")
render {
case AcceptsMp3() => ???
}
}
次ページ: 非同期 HTTP プログラミング