Finatra やるぞい (①セットアップ編)

## レポジトリ
https://github.com/eddix-ibanez/twitter-clone-finatra

## Finatraとは

  [公式]() から引用
  >Finatra is a Scala services framework built on top of    TwitterServer and Finagle.

  twitterが開発している [tiwtterServer](https://twitter.github.io/twitter-server/) と [Finagle](https://twitter.github.io/finagle/guide/) を土台にしてでできたフレームワークです。

## セットアップ
 めっちゃセットアップが楽です。コピペでローカルは立ち上がります。(例外があったらすみません)
こちらを参考にしました：https://qiita.com/TakashiOshikawa/items/53dcc42f0ab6c6377f7a
メモとしても書いていくので参考にしていくソースものっけていきます。(Githubのissueとか)

### 環境

- MacOS X
- Intellij IDEA (*)
- sbt

(*) ターミナルからでも構築できます。

### プロジェクト作成

２つ方法を紹介します。

- [intelliJを使う](https://qiita.com/analsky/items/06c2666fb0e85a4c85ed#intellijを使う)
- [`sbt new` する (推奨)](https://qiita.com/analsky/items/06c2666fb0e85a4c85ed#sbt-new-する)

#### intellijを使う

##### intelliJに Scalaプラグインを導入

intellijを開いて `⌘,` を叩くと設定画面が出てくるので左上の検索窓に`plugins`と入力して`Enter`
次に真ん中の検索窓に`Scala`と入力し`Enter`。
でできましたこいつです。

![スクリーンショット 2019-03-03 18.19.00.png](https://qiita-image-store.s3.amazonaws.com/0/212928/67b7b047-bbec-1731-9dca-e49112445ae4.png)

インストールクリックして右下のapplyを押せば完了。

##### 再起動してプロジェクトを作成

この画面が表示されるので `+ Create New Project` を押下。

![スクリーンショット 2019-03-03 18.31.40.png](https://qiita-image-store.s3.amazonaws.com/0/212928/5f6d184a-55a6-61a0-f60f-5a262dba99a5.png)

左側から scala を選択すると真ん中に選択肢が出てきます。

![スクリーンショット 2019-03-03 18.39.47.png](https://qiita-image-store.s3.amazonaws.com/0/212928/79933c2f-4838-e887-6a61-d2511a0b994c.png)

`stb` を選択して `Next` を押下するとプロジェクトの名前やディレクトリを尋ねられるので適当に入力して進んでください。
するとエディタ画面になって勝手にディレクトリ構造ができています。

![スクリーンショット 2019-03-03 18.40.59.png](https://qiita-image-store.s3.amazonaws.com/0/212928/7dfb446c-6c31-3965-d112-ecd6cc84205c.png)

#### ビルド定義

次にベースディレクトリ直下にある `build.sbt` に次のコードをコピペしてください。すでに出来ているコードもいりません。

```build.sbt
lazy val root = (project in file(".")).
  settings(
    name := "twitter-clone",
    scalaVersion := "2.12.8",
    libraryDependencies ++= dervy,
    resolvers ++= resolve
  )

lazy val dervy = {
  Seq(
    "com.twitter" %% "finatra-http" % "19.2.0"
  )
}

lazy val test = {
  Seq("com.twitter" %% "finatra-http" % "19.2.0" % "test" classifier "tests")
}

lazy val resolve = {
  Seq(
    Resolver.sonatypeRepo("releases"),
    "Twitter Maven" at "https://maven.twttr.com"
  )
}
```

これで保存すると右下に`Sync dependency`とかなんかニョキッと出てくるのでSync(同期)する方を押してください。IntelliJが勝手にfinatraの依存関係を注入(同期)してくれます。
次の項目は飛ばしてください。

### sbt new する

好きなディレクトリで

```shell
sbt new robinske/hello-finatra.g8
```

プロジェクト名を聞かれますがここも好きにしてください。
するとこんな感じ。

```
himatra/
├── build.sbt
├── project
│   └── build.properties
└── src
    └── main
        ├── resources
        │   └── logback.xml
        └── scala
            └── Server.scala
```


#### サーバーの起動、ルーティング処理を追加

`./src/main/scara/main.scala`に以下のコードをコピペしてください。

```main.scala
import com.twitter.finagle.Http
import com.twitter.finagle.http.Request
import com.twitter.finagle.stats.NullStatsReceiver
import com.twitter.finagle.tracing.NullTracer
import com.twitter.finatra.http.filters.HttpResponseFilter
import com.twitter.finatra.http.routing.HttpRouter
import com.twitter.finatra.http.{Controller, HttpServer}

object Main extends FinatraBenchmarkServer

class FinatraBenchmarkServer extends HttpServer {
  // 色々な設定項目はBaseHttpServerを参照
  // override def defaultFinatraHttpPort: String = ":9000"
  // override def defaultHttpServerName: String = "0.0.0.0"

  override def configureHttpServer(server: Http.Server) = {
    server
      .withCompressionLevel(0)
      .withStatsReceiver(NullStatsReceiver)
      .withTracer(NullTracer)
  }

  override def configureHttp(router: HttpRouter): Unit = {
    router
      .filter[HttpResponseFilter[Request]]
      .add[FinatraBenchmarkController]
  }
}

class FinatraBenchmarkController extends Controller {
  private[this] val helloWorldResponseText = "Hello, World!"

  get("/json") { request: Request =>
    Map("message" -> "Hello, World!")
  }

  get("/plaintext") { request: Request =>
    helloWorldResponseText
  }
}
```

保存したらsbt shell (なかったら画面左下のそれっぽいとこをクリックして出てくる。) で 

```shell
sbt:project-name> run -http.port=:9000 -http.name=:localhost
```

を叩く。

```
[info] Running Main -http.port=:9000 -http.name=:localhost
```
と出てきたらOK

<font color="Red">
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
</font>

とか出てくるけど無視してオッケーです。

#### 確認

自分は[Postman](https://www.getpostman.com)を使っています。cURLだとダメでした。
`http://localhost:9000/json`を叩いてみましょう。

![スクリーンショット 2019-03-03 19.10.05.png](https://qiita-image-store.s3.amazonaws.com/0/212928/1c1114a8-e830-2908-26a7-1bdd7d9f5807.png)

`{"message":"Hello, World!"}`と返ってきたら成功。

ちなみにヘッダは

```header.txt
Date : Sun, 03 Mar 2019 07:00:03 GMT
Server : Finatra
Content-Length : 27
Content-Type : application/json; charset=utf-8
```

以上。