スパイシー...
Spiffy は、Scala、Akka (Scala アクター実装)、および Java Servlet 3.0 API を使用する Web フレームワークです。これは、非同期インターフェイスを利用し、Web アプリケーションに大規模な並列性とスケーラブルな環境を提供することを目的としています。 Spiffy のさまざまなコンポーネントはすべて、少量の作業を非常に迅速に実行し、パイプライン内の次のコンポーネントにリクエストを渡す、独立した最小限のモジュールである必要があるという考えに基づいています。最後のコンポーネントがリクエストの処理を完了すると、リクエストを「完了」してクライアントに送り返すことで、サーブレット コンテナに信号を送ります。
いくつかのルートを追加します。
// index page, no code, just text
"""^/$""".r -> "Welcome to Spiffy!",
// main news page
new Regex("""^/(news)/$""") -> NewsController(),
// view some news by id
new Regex("""^/(news)/(view)/(d+)/$""") -> NewsController()
コントローラーを書きます。
def receive = {
// handles "news/add/"
case ControllerMsg(List("news", "save"), req, res, ctx) => {
// run validation on the request using Spiffy's validation DSL
var errors:Map[String, Set[String]] = validate (req) (
"email" as email confirmedBy "email_confirm",
"email_confirm" as email,
"title" as (string, 32),
"body" as string,
"tag" as string optional
) match {
case Some(List(errs,warns)) => { // Problem validating
errs
}
case None => None.toMap // passed validation
}
}
// handles "/news/"
case ControllerMsg(List("news"), req, res, ctx) => {
// load up news and stuff in map then render
val params = loadNews
view() ! ViewMsg("news", params, req, res, ctx)
}
// handles "/news/view/$newsId/"
case ControllerMsg(List("news", "view", newsId), req, res, ctx) => {
// usually you want to load the item, in this example we dont
// load item and set the params that the view will render
val news = loadNewsItem(newsId)
val params:Map[Any,Any] = Map("news" -> news)
// ask the view to render
view() ! ViewMsg("newsView", params, req, res, ctx)
}
}
次に、いくつかのテンプレートを作成します。この例の詳細については、NewsController と SpiffyConfig を参照してください。
現時点では、Spiffy を使用するには、jar (mvn jar:jar) をビルドし、アプリケーションのクラスパスに追加する必要があります。次の環境変数も定義する必要があります (context.xml で定義できます)。
<Environment name="SpiffyConfigObject" value="org.spiffy.config.SpiffyBuiltinConfig" type="java.lang.String"/>
org.spiffy.config.SpiffyBuiltinConfig
、 org.spiffy.config.SpiffyConfig
を拡張し、必要な値をすべて提供するオブジェクトに置き換える必要があります。例として SpiffyConfig を見てみましょう。
Spiffy は、Akka アクターを利用して、そのさまざまなコンポーネントをすべて区画化し、分離します。 Spiffy パイプラインのすべてのコンポーネント (最初のフィルターを除く) は、Akka アクターのプールで構成されます。 Spiffy アクターは、さまざまな種類のディスパッチャの負荷分散プールによってサポートされています。
Spiffy はフィルターとして実装されています。フィルターはリクエストを受信すると、それを非同期モードにしてルーターに送信します。次にルーターは、リクエスト URL を検査し、既知のコントローラー マッピングのリストと照らし合わせて評価することで、リクエストをどう処理するかを決定します。マッピングは、要求された URL と一致し、それを対応するコントローラーに割り当てる正規表現です。一致するものが見つかった場合、ルーターはコントローラーにリクエスト (およびリクエストと一緒に送信する必要があるすべてのオブジェクト) をメッセージで送信します。その時点でルーターの仕事は完了し、新しい受信リクエストを自由に処理できるようになります。コントローラーはリクエストを受信すると、リクエストに対して必要なロジックを実行し、リクエストを終了するか、Spiffy の別のコンポーネント (通常はビュー ハンドラー) に渡すかを決定できます。
Spiffy はフックの概念を使用して、フレームワークのパイプラインの特定のコンポーネントの前後でカプセル化して実行できるロジックを実行します。フックはコントローラーとビューの前後で実行できます。コントローラーがコントローラーを完全にバイパスすることを決定する前に実行されるフック、またはコントローラーが操作する機会を得る前に認証やリクエスト自体の変更などのロジックを単に実行する可能性があります。コントローラーの後に実行されるフックは、リクエストを別のコントローラーに再ルーティングしたり、そこで変更したり、終了してからクライアントに送り返すこともできます。同じロジックがビューの前後で使用され、フックによってビューのレンダリングを完全に停止したり、レンダリングされた出力をフレームワークの別の部分に渡して、レンダリングされた出力に対して追加の作業を実行したりできます。