Akka HTTPのごく最低限のWEBサービスに必要なルーティングDSL


スコープ

タイトル通り、とりあえずAkka HTTP使ってみたい人が最初に使うルーティングのDSLについてのメモ。ごくごく最低限です。
(実践寄りのAkka Streamのソースとして使うとかはこの記事で触れないのでその辺知りたい方はそっ閉じでOKです

とりあえず書いてみた

build.sbt(一部だけ)
libraryDependencies += "com.typesafe.akka" %% "akka-http-experimental" % "2.4.2"
Main.scala
import java.util.concurrent.ConcurrentHashMap

import scala.collection.convert.decorateAsScala._

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives

object Main extends App {
    implicit val system = ActorSystem("my-system")
    implicit val materializer = ActorMaterializer()

    val piyoMap = new ConcurrentHashMap[Int, Map[String, List[String]]]().asScala

    import Directives._
    val route = path("hoge") {
        (get | post) {
            getFromResource("moge.txt")
        }
    } ~ pathPrefix("piyo" / ".+".r) { str =>
        pathEnd {
            sys.error("bomb!!")
        } ~ path(IntNumber) { num =>
            get {
                val piyoOpt = piyoMap.get(num)
                complete(s"${str}, ${num}, ${piyoOpt}")
            } ~ post {
                formFieldMultiMap { form =>
                    piyoMap.put(num, form.toMap)
                    complete(s"${str}, ${num}, ${form}")
                }
            }
        }
    }

    Http().bindAndHandle(route, "localhost", 8080)
}

要約

  • akka.http.scaladsl.server.Directives._ をimportしたらDSLが使える
  • パス情報の構文(pathなど)とHTTPメソッドの構文(get postなど)で絞り込んでネストしてルーティングを作る
  • パスの文字列を取りたい時は正規表現やIntNumber構文などをパスの引数に仕込めばOK。次のネストでラムダのパラメータとして使える。
  • ルーティングを追加する構文: ~
  • パス情報をネストしたい時の構文: pathPrefix
  • パス情報をネストしたがここでマッチさせたい時の構文: pathEnd
  • クエリパラメータをとりたい時の構文: formFieldMultiMap
  • 500 InternalServerErrorを返す構文: sys.error
  • ルーティングがマッチしなければ、404 Not Found が返される
  • もっと細かいことがしたければ公式文書みてください http://doc.akka.io/docs/akka/2.4.2/scala/http/routing-dsl/index.html

個人的な感想

お手軽だけど自分はあまり使わない・・かも??

個人的には、どっちかっていうとこの手のルーティングは設定ファイルに持たせたい派。
コンパイル言語のハードコードのDSLだし運用面のメリットは特にないかも・・的な印象を途中から感じ始めた。
もし本番で使うんだったら、(使い方やリリース頻度によるけど、)できればこのへんは動的にリロードしたいところ。

せっかくなので、次はakka-http-coreの方勉強しようと思います。