finatra
finatra(https://twitter.github.io/finatra/)はSinatraからアイデアを得て、twitterSeverを使って作られたScalaベースのwebフレームワークです。この記事を書いた時点で、最新のバージョンは2.0
です。
Hello World
finatraのリポジトリ(https://github.com/twitter/finatra)にあるexamples/finatra-hello-world
を使います。
README.md
には既に詳しいディプロイ方法が載ってありますが、起動方法は下記のコマンドを叩く:
./sbt -Dlogback.configurationFile=src/test/resources/logback-test.xml run
portを変える
このプロジェクトはデフォルトに8888
(フロント)と9990
(内部用)を使っていますが、もしいずれかのport
は既に他のアプリに使われたりしたら、エラーがでます。port
を変えるには、run
の後ろに、-http.port=:1212
(フロント)、-admin.port=:9911
(内部用)というオプションを追加してください。
ブラウザを開いて、http://localhost:8888/hi?name=Worldにアクセスすると
ServerとControllerをつくてみる
先ほどのHello Worldプロジェクトでは、既にHelloWorldSever
とHelloWorldController
が
用意されたので、特に何もしなくてもサイトとして動きます。これから、自分でServerとControllerを作ってみます:
Server
./src/main/scala/jp/co/befool/bii
にBiiServer.scala
を作成します。
この記事のコードがパッケージ
jp.co.befool.bii
にあります。パッケージというコンセプトが分かる方は、自分好きなパッケージにしても大丈夫です。
package jp.co.befool.bii
import com.twitter.finatra.http.HttpServer
import com.twitter.finatra.http.routing.HttpRouter
import com.twitter.finatra.http.filters.CommonFilters
// finatraのHttpServerを拡張
class BiiServer extends HttpServer {
// routerなど設定
override def configureHttp(router: HttpRouter) {
router
.filter[CommonFilters] // Commonフィルターが必要です
}
}
// BiiServerのエントリーポイント
object BiiServerMain extends BiiServer
Controller
./src/main/scala/jp/co/befool/bii/controller/RootController.scala
を作成します:
package jp.co.befool.bii.controller
import com.twitter.finatra.http.Controller
import com.twitter.finagle.http.Request
// finatraのControllerを拡張
class RootController extends Controller{
// http://localhost
get("/") { request: Request =>
response.ok.body(s"<h1>HelloWorld</h1>")
}
}
BiiServer
からRootController
にルートします:
import jp.co.befool.bii.controller.RootController
// finatraのHttpServerを拡張
class BiiServer extends HttpServer {
// routerなど設定
override def configureHttp(router: HttpRouter) {
router
.filter[CommonFilters] // Commonフィルターが必要です
.add[RootController] // RootControllerを追加
}
}
コマンドsbt run
すると
[warn] Multiple main classes detected. Run 'show discoveredMainClasses' to see the list
Multiple main classes detected, select one to run:
[1] com.twitter.hello.HelloWorldServerMain
[2] jp.co.befool.bii.BiiServerMain
Enter number:
サーバーが二つ検出されたので、どっちを実行するかという質問です。2
で入力します。問題なければ、ブラウザでhttp://localhost:8888
で見ると:
サーバーちゃんと動いています。
RequestのValidationをやってみます
先ほど作ったRootController
の直前に、RootRequest
を作成します:
import com.twitter.finatra.request.QueryParam
import com.twitter.finatra.validation.NotEmpty
case class RootRequest (
// @NotEmpty記号は空値が不可ということです
// @QueryParamは@NotEmptyの対象パラメータ名です
@NotEmpty @QueryParam name: String
)
RootController
のget("/")
ルートに修正を入れます:
get("/") { request: RootRequest =>
response.ok
.header("Content-Type", "text/html; charset=utf-8")
.body(s"<h1>こんにちは、${request.name}</h1>")
}
request
のタイプを先ほど作ったRootRequest
に宣言します。
sbt run
して、ブラウザでhttp://localhost:8888
にアクセスして、下記のエラーが表示されます:
URLをhttp://localhost:8888/?name=世界
にして、アクセスすると:
Request
のバリデーション動いてるとわかりますね。
まとめ
finatraに興味ある方は、より詳しい説明と使い方が公式のリポジトリに載っています:https://github.com/twitter/finatra/blob/master/http/README.md。
オープンソースのwebフレームワークとしては、finatraのドキュメントなどはまだ不足してる感じがします。しかし、twitterという超大手なweb企業が使ってるというとこが、魅力を感じる人もいるでしょう(自分はそうでした)。次回はfinatra
を利用してアプリのバックエンドを作ってみようと思います。