Get started Scala Playframework2.6

# はじめに
ここではScalaでPlayframeworkのHello world的なプロジェクトを作るところまでを解説します。とりあえず動かせる・作れることを優先しているので、作成時の流行り廃りや主観がかなり混じってます。必要に応じて別サイトなどで補完してください。

# はじめる前に
## Playframeworkとは
Scalaでおそらく一番シェアの高いWebFrameworkです。とりあえずScala使ってWebアプリ作りたいなら特に理由が無い限りはPlayframeworkでよくない的な。Playframework自体はあまり多機能ではなく、frameworkに依存せず使えるライブラリを多数組み合わせて使うのが一般的です。デフォルトでステートレスかつ並列にリクエストを処理できます。

## Scalaとは
JavaVM上で動く、関数型言語とオブジェクト指向言語のいいとこ取りをしたような言語です。Javaの既存のライブラリ資産が使える、副作用の少ないコードが簡潔に書ける、強力な静的型サポート、リッチなコレクションライブラリ、高速かつ強力なGCを持つJVM上で動く、などがウリです。ただしプリミティブな低レイヤーのコードを書くのは、現状だと間違いなく辛いでしょう。

## 参考にするべきドキュメント
### Playframework公式
2.6の場合はこちらです。 https://playframework.com/documentation/2.6.x/
Major Versionが上がると大きく変更が入ることが多いFrameworkであるため、最新版を参考にするのがベストです。日本語訳版もありますが、更新が遅いので英語版をお勧めします。

### Scala標準ライブラリ
http://www.scala-lang.org/api/current/
特に豊富なコレクションライブラリの機能を確認するために何度も読むことになると思います。100回読め。

### コップ本
正式名「Scalaスケーラブルプログラミング」です。第3版が2016年9月に出ました。
Scalaの言語機能を日本語で網羅している唯一と言っていいドキュメントです。著者はScalaを作ったMartin Odersky先生です。

# システムに必要なもの
## JDK
最新の安定板のJDKをインストールしましょう。Play2.6ならJDK8の最新版。(JDK9以降は地雷が多い印象です)正しくインストールされていればコンソールで以下のような表示が出る筈です。

```shell-session
$ java -version
openjdk version "1.8.0_144"
OpenJDK Runtime Environment (build 1.8.0_144-b01)
OpenJDK 64-Bit Server VM (build 25.144-b01, mixed mode)
```

## sbt
Scala界でデファクトスタンダードになっているビルドツールですが、大体こいつ一発で開発環境は一通り揃います。こちらもできるだけ最新のものを。最近はbrewなりaptなりのパッケージマネージャに任せれば一発で入ると思います。

インストールされていれば、以下のように確認できます

```shell-session
$ sbt about     
[info] Loading project definition from /home/yosuke/project
[info] Set current project to yosuke (in build file:/home/yosuke/)
[info] This is sbt 1.0.0
[info] The current project is {file:/home/yosuke/}yosuke 0.1-SNAPSHOT
[info] The current project is built against Scala 2.12.3
[info] Available Plugins: sbt.plugins.IvyPlugin, sbt.plugins.JvmPlugin, sbt.plugins.CorePlugin, sbt.plugins.JUnitXmlReportPlugin, sbt.plugins.Giter8TemplatePlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.12.3
sbt about  20.46s user 0.54s system 432% cpu 4.855 total
```

## エディタ
このへんは好みと宗教に応じてどうぞ。

### IntelliJ
最も初期にScala対応が充実していたため特にベテランユーザに良く使われるIDE。無料のCommunityEditionであまり問題はありません。有料版だとWeb開発系機能が充実していて便利です。

### Eclipse
Java系ならEclipseだよねーという感じですかね。Javaから移行した組が結構使っているようです。

### その他
Emacsはscala-mode2を一応入れてますが、多用はしないので分からないです。Vimで開発している人もいるので使えないことはない筈だけど良く知らない。その他コメントで追記してもらえれば追加します

# 初期プロジェクト作成
色々やり方はありますが、今ならsbt newを使うのがてっとり早いでしょう。これ以降は太いインターネット回線を持ったところでやってね。

```shell-session
$ sbt new playframework/play-scala-seed.g8
```

これで必要な諸々をダウンロードしてきます。終わると

- project name
- organization name(後で解説します
- scalatestplusplay_version
- play_version

を聞かれます。下2つは標準で最新のものになるのでそのままEnterで標準が選択されます。選んでおしまいです。

昔のScalaを知っている人向けに解説すると、昔、giter8というGitHubから雛形プロジェクトを持ってくるツールがありましたが、その機能がsbtに取り込まれてnewコマンドとして実装された感じです。ちなみにactivatorは死にました。さようなら。(activatorの墓AA略

## Organization name
Java固有のパッケージネーム文化です。URLのホスト名を逆にしたものをパッケージ名とすることにより、名前空間が被らないようにします。例えば `github.com` であれば `com.github` などとします。一般にそのホストを所持していることが望ましいです。稀に従わないパッケージがあり、scala標準ライブラリの `scala` 、Playframework標準の `play` 、Javaでそこそこ有名なtwitterライブラリTwitter4Jの `twitter4j` パッケージなどがあります。個人であれば `com.github.'username'` なども良く使われます。

またややこしい話として、PlayframeworkのWebApplicationではOrganization nameを区切らないのが一般的です。複数のWebApplicationの名前空間が被ったところで困らないからです。

## 動作確認
作成されたプロジェクトディレクトリに入り、

```shell-session
$ sbt
```

とすると、必要な諸々を大量にダウンロードの後にsbtの対話インターフェースが起動します。このダウンロードは初回だけなので安心してください。そのまま

```shell-session
[project] $ run

...

--- (Running the application, auto-reloading is enabled) ---

[info] p.c.s.AkkaHttpServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Enter to stop and go back to the console...)

```

と実行すれば、ダウンロード後にサンプルプロジェクトのサーバが起動します。`localhost:9000`にブラウザでアクセスし、エラー以外が表示されれば成功です。この画面はコードを変更したとき、勝手に追従してくれます。

## 初期設定の補足
PlayframeworkにはFilterという概念があり、全てのリクエストに対してヘッダを追加したりといった処理をするのに使います。

初期設定でCSRFilter, AllowedHostFilter, SecurityHeadersFilterが有効になっています。

### SecurityHeaderFilter
Content-Security-HeaderをONにするものです。セキュリティ的な効能は詳しくないので割愛しますが、例えCDNからJSを持ってくるようなHTMLを書くとJSのロードに失敗する問題を引き起こすので、CDNを使う場合は適切に設定する必要があります。

### AllowedHostFilter

また、AllowedHostFilterで許可するHostに初期設定があるので、このまま本番投入してしまうと何故か本番だと動かないということが起こり得ます。注意!

# ライブラリ選定
`build.sbt`にはプロジェクト設定があり、ここにライブラリ依存を書き足していくことができます。デフォルトではDBアクセスすらできないので適当に追加していきましょう。

## ORM
ほぼ全てのWebApplicationはDBが必要であり、多くの場合RDBのレコードをオブジェクト指向言語のオブジェクトに変換してくれる、ORMを使用します。ちなみに以下に加えてRDBMSに繋ぐバインディング(MySQLならmysql-connector-javaなど)が必要です。

### SkinnyORM
初っ端から他FrameworkのORMですが割とオススメです。ScalikeJDBCをリッチにしたようなやつで、そこそこ自動でやってくれつつ、複雑なクエリを書きたいときはScalikeJDBCライクにゴリゴリ書けるのがウリです。

### ScalikeJDBC
DB接続機能しか持たないJavaのAPIとしてJDBCという底レイヤーなものがありますが、そのScala版を謳うだけあり、ORMに一般には含まれないDB Connectionライブラリです。ただし頑張ればORMっぽいことができます。

### Slick
割と関数型チックにDBに繋げるORM(前述のSkinnyORMが割とゴリゴリオブジェクト指向なので)らしいし、Play2.5では標準だったしシェアは高い筈なんですが、なぜか不評で使ったことないです…(詳しいマンがきっと追記してくれる

## JSON
標準の状態でもJSONを扱うことができますが、オブジェクトの定義が面倒くさくて不評なので別のライブラリが使われることも多いようです。

### Circe(キルケー?)
case classのSerialize、Deserializeがとても簡単にできる。現状欠点としてはScala2.12以降でないとマトモに動かないことぐらい。Playで使う場合はplay-circeを入れるといいです。

### json4s
case classまわりが優秀で、一時期デファクトと言えるぐらい流行りましたが、実装に若干の問題があって移行する動きがみられます。Playで使う場合はplay-json4sを使いましょう。

## その他
DBマイグレーションツールとしては、play-flyway(JavaのFlywayをPlayframeworkで使えるようにする)などがあります。多くの場合必要になる認証まわりはSilhouetteとか良さそうです(使ったことはない)

# おわりに
最後の方雑になってしまいましたが、とりあえずこれでPlayframeworkをはじめることができるとおもいます。あとは`conf/routes`ファイル、`app/controller`ディレクトリのcontrollerを書き加えていくことで、URLと実行する処理を追加していけばいいでしょう。