AirframeのFinagleサポートを試してみる

AirframeScala向けのDIコンテナを中心とした様々な便利機能を提供するプロジェクトなのですが、最近airframe-httpとairframe-http-finagleというモジュールが追加され、Finagleを使ったWebアプリケーションを簡単に作れるようになったので感じを掴むために軽く試してみました。

まず、build.sbtの依存関係はこんな感じ。

libraryDependencies ++= Seq(
  "org.wvlet.airframe" %% "airframe-http"         % "0.66",
  "org.wvlet.airframe" %% "airframe-http-finagle" % "0.66",
  "org.wvlet.airframe" %% "airframe"              % "0.66"
)

Webアプリケーションの実際の処理を作ります。ルーティングやパラメータのマッピングなどはアノテーションで指定する方式です。また、ケースクラスを返すと自動的にJSONレスポンスを返してくれるようです。とりあえずハローワールド的な感じでGETメソッドでパスパラメータを1つ受け取るだけのエンドポイントを定義しています。

import wvlet.airframe.http._

object MyResource {
  case class User(name: String)
}

trait MyResource {
  import MyResource._

  @Endpoint(path = "/user/:name", method = HttpMethod.GET)
  def getUser(name: String): User = User(name)

}

これを以下のようなMainオブジェクトで実行します。最小構成だとこんな感じですが、動作に必要なコンポーネントはAirframeのDI機能で合成されているので、いろいろカスタマイズすることが可能です。

import wvlet.airframe.http._
import wvlet.airframe.http.finagle._

object Main extends App {
  val router = Router.of[MyResource]

  val module = finagleDefaultDesign
    .bind[MyResource].toSingleton
    .bind[Router].toInstance(router)
    .bind[FinagleServerConfig].toInstance(
      FinagleServerConfig(port = 8080))

  module.build[FinagleServer] { server =>
    server.waitServerTermination
  }
}

ひとまずこれで動作を確認することができました。

Finagleを直接使うのはまあまあしんどいので、普通のWebアプリっぽく実装できるのはいいですね。また、httpサポートとfinagleサポートのモジュールが分割されているので将来的に他のバックエンドで動かすということもできるようになるかもしれません。