Finchを試してみる
FinchはFinagle(twitter製のサーバライブラリ)をベースにした、簡単に信頼性の高いAPIが構築できる、軽量なHttpフレームワークである。そして、ほぼFinagleと変わらないパフォーマンスを目指しているという。
定番のHello World
scala
の開発では、sbt
というビルドツールをよく使われる。
sbt初めての方、素晴らしい記事をどうぞ:
https://qiita.com/prokosna/items/0728b73561955e631937
まずsbt
用プロジェクトのディレクトリを用意する:
tree -L 3
.
├── build.sbt
├── project
│ ├── build.properties
│ └── target
├── src
│ └── main
│ └── scala
└── target
./build.sbt
はベース設定で、./project/build.properties
の記述で個別の設定を上書きすることができる。
まず./build.sbt
に下記のように設定を書く:
// ビルド情報
name := "hello-world"
version := "1.0"
// バージョンを定義
val circeVersion = "0.11.1"
val finchVersion = "0.29.0"
// 依存を追加
libraryDependencies ++= Seq(
"com.github.finagle" %% "finchx-core" % finchVersion,
"com.github.finagle" %% "finchx-circe" % finchVersion,
// JSONライブラリ https://circe.github.io/circe/
"io.circe" %% "circe-generic" % circeVersion,
)
そして、アプリのエントリーポイントのsrc/main/scala/main.scala
を作る:
import cats.effect.IO
import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http.{Request, Response}
import com.twitter.util.Await
import io.finch._
import io.finch.catsEffect._
import io.finch.circe._
import io.circe.generic.auto._
// scalaではextends Appすることで、アプリケーションを作成する
// objectはscalaでのsingleton, 他の言語でのstaticだと思えば
object Main extends App {
// クラス
case class Message(hello: String)
// デフォルトエンドポイント
def healthcheck: Endpoint[IO, String] = get(pathEmpty) {
Ok("OK")
}
// /helloエンドポイント
def helloWorld: Endpoint[IO, Message] = get("hello") {
Ok(Message("World"))
}
// /hello/{s} エンドポイント {s}はs:Stringに渡される
def hello: Endpoint[IO, Message] = get("hello" :: path[String]) { s: String =>
Ok(Message(s))
}
// サーバーを初期化
// エンドポイントの登録など
def service: Service[Request, Response] = Bootstrap
.serve[Text.Plain](healthcheck)
.serve[Application.Json](helloWorld :+: hello)
.toService
// listen
Await.ready(Http.server.serve(":8081", service))
}
最後に
sbt run
でコンパイル+実行。
サーバー無事にupになったら、下記のエンドポイントをアクセスしてみると、下記のリスポンスパターンが確認することができる。
curl http://localhost:8081
OK
curl http://localhost:8081/hello
{"hello":"World"}
curl http://localhost:8081/hello/my-finch
{"hello":"my-finch"}
curl http://localhost:8081/hello/my-finch/and-world
表示なし(HTTP ERROR 404)
最後に
単純なAPIを作るなら意外と簡単だが、他のサービス(DB、キャッシュ)など絡んで作る場合はどうなるんだろうと思いつづも、scala
のエレガントさに魅力を感じた。まだ中身しっかり理解してないが、次回はすこし中身を少し解読して共有しようと思う。