§コンテンツネゴシエーション
コンテンツネゴシエーションとは、同一のリソース (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 プログラミング