§Play 2 HTTP API 概論
§EssentialAction とは?
EssentialAction は古い Action[A] に変わる、よりシンプルな新しい型です。 EssentialAction を理解するには Play 2 のアーキテクチャを理解する必要があります。
Play 2 は Web プログラミング作業を簡単にするための大量の有用な API やサービス、構造がありますが、それらが囲んでいるコアは本当に小さくなっています。
基本的には、 Play 2 は概念的に以下の型を持つ API です。
RequestHeader -> Array[Byte] -> Result
上の 計算 は RequestHeader
型のリクエストヘッダを受け取り、さらにリクエストボディを Array[Byte]
として受け取り Result
を生成します。
この型は、単に入力から計算をしたい場合でも、もしくは Amazon S3 のようなストレージサービスに転送したい場合でも、リクエストボディ全体をメモリ (もしくはディスク) に置く事が前提となってしまいます。
むしろ、リクエストボディの断片をストリームとして受け取り、必要であれば段階的に処理できるようにする事が望まれます。
二つ目の矢印で入力を断片として受け取り、結果を生成ようにする事が必要です。まさにこれをするクラスがあります。それは Iteratee
と呼ばれ、二つの型パラメータを持ちます。
Iteratee[E,R]
は E
型の断片を入力として受け取り、最終的に R
を返す 矢印 型です。Play の API では、断片化された Array[Byte]
を受け取り、最終的に Result
を返す Iteratee が必要です。そのため、以下のように型を少しだけ変えます:
RequestHeader -> Iteratee[Array[Byte],Result]
最初の矢印では =>
の別名を持つ Function[From,To] をそのまま使います。
RequestHeader => Iteratee[Array[Byte],Result]
ここでもし Iteratee[E,R]
の別名の中置記法での型を定義した場合、
type ==>[E,R] = Iteratee[E,R]
となり、さらに面白い方法で型を書くことができます:
RequestHeader => Array[Byte] ==> Result
そしてこれは以下のように読めます: リクエストヘッダを受け取り、リクエストボディを表す Array[Byte]
を断片として受け取り、最終的に Result
を返す、と。これがまさに EssentialAction
型の定義です:
trait EssentialAction extends (RequestHeader => Iteratee[Array[Byte], Result])
一方 Result
型は概念的にはレスポンスヘッダとレスポンスボディとして考えることができます:
case class Result(headers: ResponseHeader, body:Array[Byte])
しかし、もしレスポンスボディの全てをメモリに格納せずに、段階的にクライアントに送りたい場合はどうすれば良いでしょうか。型を改善する必要があります。ボディの型を Array[Byte]
ではなく、断片化された Array[Byte]
を生成する何かに置き換える必要があります。
このための Enumerator[E]
と呼ばれる型があり、断片化された E
を生成する事が出来ます。 Play の場合は Enumerator[Array[Byte]]
になります。
case class Result(headers:ResponseHeaders, body:Enumerator[Array[Byte]])
もしレスポンスを段階的に送る必要がない場合は、ボディ全体を一つの断片として送ることができます。
Array[Byte]
に変換できれば、言い換えると E
に対してそれを補償する Writeable[E]
があれば、あらゆるタイプのデータをソケットに書き出すことができます。
case class Result[E](headers:ResponseHeaders, body:Enumerator[E])(implicit writeable:Writeable[E])
§要点
Play 2 の原始的な HTTP API はとてもシンプルです。
RequestHeader -> Iteratee[Array[Byte],Result]
さらに面白く書くと、
RequestHeader => Array[Byte] ==> Result
以下のように読みます: RequestHeader
を受け取り、 Array[Byte]
の断片を受け取り、そしてレスポンスを返す。レスポンスは ResponseHeaders
とボディからなり、ボディはソケットに書き出される Array[Byte]
へと変換出来る値の断片であり、 Enumerator[E]
として表現されます。
次ページ: HTTP フィルター