Unfilteredでのリクエストのルーティング

Unfilteredではパターンマッチを使用してリクエストのルーティングを行います。パターンマッチのための抽出子には様々なものが用意されており、柔軟なルーティングが可能になっています。利用可能な抽出子には以下のようなものがあります。

抽出子 説明
GET GETメソッドでのリクエストにマッチします。
POST POSTメソッドでのリクエストにマッチします。
PUT PUTメソッドでのリクエストにマッチします。
DELETE DELETEメソッドでのリクエストにマッチします。
HEAD HEADメソッドでのリクエストにマッチします。
Path リクエストパスに対するマッチングを行います。
ContextPath リクエストパスのうちコンテキスト名を除いたパスに対するマッチングを行います。
Seg Pathと組み合わせてリクエストパスの部分マッチングに使用します。
Params リクエストパラメータを抽出します。
Cookies クッキーを抽出します。

以下はリクエストメソッドとパスによるパターンマッチの例です。

def intent = {
  // GETメソッドによるドキュメントルートに対するリクエスト
  case GET(Path("/")) => Ok ~> Html(<p>Hello Unfiltered!</p>)

  // GETメソッドによる/inputに対するリクエスト
  case GET(Path("/input")) => Ok ~> Html(
    <form action="result" method="POST">
      <input type="submit"/>
    </form>)

  // POSTメソッドによる/resultに対するリクエスト
  case POST(Path("/result")) => Ok ~> Html(<p>Hello World!</p>)

  // メソッドは関係なく/worldに対するリクエスト
  case Path("/hello") => Ok ~> Html(<p>こんにちは世界!</p>)
  
  // HEADメソッドによるすべてのリクエスト
  case HEAD(_) => Ok ~> Html(<p>すべてのHEADリクエスト</p>)
  
  // どのパターンにもマッチしなかった場合
  case _ => NotFound ~> Html(<p>Not Found!</p>)
  
}

以下のようにパスをPathとSegの組み合わせで指定することで一部のリクエストパスの一部を変数にバインドし、マッチした際に実行される処理の中で使用することもできます。

// GETメソッドによる/hello/{name}に対するリクエスト
case GET(Path(Seg("hello" :: name :: Nil))) 
  => Ok ~> Html(<p>Hello {name}!</p>)

Pathの代わりにContextPathを使うことでWebアプリケーションのコンテキスト名を除いたパスに対するマッチングを行うことができます。開発環境と運用環境とでコンテキスト名が異なる場合などに対応することができます。

case GET(ContextPath(_, "/hello"))
  => Ok ~> Html(<p>Hello Unfiltered!</p>)

というわけで、こんな感じで抽出子を組み合わせることで様々なルーティングを行うことができます。この他にもBASIC認証でルーティングを行うための抽出子なんかも用意されていたりします。この強力なルーティング機能はUnfilteredの特徴の1つといえますね。