テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

spray: extractionでルーティングをダイナミックに生成する

https://groups.google.com/forum/#!topic/spray-user/hyMgl89VQFQ

sprayは, Directiveによってルーティングのパターンマッチングを構築する. しかしDirective型は, inner routeの評価についてどれも常に同じ戦略をとるわけではない. extractionをする場合はdynamicに評価をするが, それ以外はルーティングが生成された時に一度だけ実行される. 前者はextract, parameterなどが相当し, 後者はnoopやmethodなどが相当する.

具体的な話をする. S3ではOPTIONSリクエストを処理する必要がある. これは, 書いてみると, 以下のような形になった. ここでの期待は, OPTIONSリクエストに対してはoptionsでマッチをして, noopよりあとの処理は実行されないことであり, これは自然な期待と言えるが実際にはそうはうまくいかない. noopの中も実行されてしまうのだ.

extract { 
  options {
    ...
  } ~ noop {
    // OPTIONSリクエストは落ちてしまう処理
  }
}

挙動を順を追って説明すると,

  1. extractされた時にルーティングが生成される.
  2. OPTIONSが突っ込んでくる
  3. optionsとnoopの間にextractionがないためnoopの中もOPTIONSリクエストが通る
  4. 落ちる

だからこのコードは, noopの部分を以下のように修正する必要がある. このextractionは本当に無意味であるので, しかるべきDirective0が用意されないかと期待する.

~ extract(_.request) { _ =>
  // ...
}

詳しくは以下を読む.

spray | Documentation » 1.2.2 / 1.3.2 » spray-routing » Advanced Topics » Understanding the DSL Structure

sprayは嵌りポイントが多い. PlayとかScalatraとかいうものはどうなのだろうか?