はじめに
この記事は、ビズリーチのPlay2とSlickを使ってWebアプリケーションを作成するハンズオンを、
Scala歴ほぼ1ヶ月の私がやってみた際に、つまづいた、または調べた内容をまとめたものです。
私と同じようにScalaの勉強を進めている方の助けになれば幸いに思います。
いくつかフレームワークとバージョンの組み合わせがあるのですが、今回は、Play2.5 + Slick3.1のハンズオンをやってみました。
以下、ハンズオン各章について、つまづいた点、調べた点をまとめていきます。
イントロダクション
-
Play2とは
- JavaとScalaのWebアプリケーションフレームワーク
-
Slickとは
- Scala Language-Integrated Connection Kit
- RDBを簡単に扱うための、ScalaのFRM(Functional Relational Mapping)ライブラリ
- Scalaのコレクションを扱うような操作でDBにアクセスし、データを操作可能
プロジェクトの作成
以下の2つは同じであるようです。
build.sbt
libraryDependencies += "com.typesafe.play" %% "play-slick_2.11.8" % "2.0.2"
scalaVersion := "2.11.8"
libraryDependencies += "com.typesafe.play" %% "play-slick" % "2.0.2"
IDEの準備
特になし
DBの準備
H2の起動
Mac, もしくはLinuxの場合、sh start.sh
で起動するのですが、その状態を維持しなくてはならないので、次の作業を行うために別でターミナルを開く必要があります。
ルーティングの定義
コントローラの雛形を作る
「controllers
パッケージにUserController
クラスを以下のように作成します。」
というのは、
「app/controllers
ディレクトリ配下にUserController.scala
を作成し、そのファイルにUserController
クラスを定義する」
ということみたいです。
- DI機能とは
- Dependency Injection(依存性注入)
- 依存関係解決、コンポーネントの動作を分離などに役立つ
ユーザ一覧の実装
ビュー
list.scala.html
はviews/user
ディレクトリを作成し、その配下に作成します。
ユーザ登録・編集画面の実装
特になし
登録・更新処理の実装
userForm.bindFromRequest
です。
userForm.bindFormRequest
ではありません。
私はこの打ち間違えに気がつかず、10分ほど無駄にしました。
削除処理の実装
特になし
JSON APIの準備
app/controllers
ディレクトリ配下にJsonController.scala
を作成し、そのファイルにJsonController
クラスを定義します。
ユーザ一覧APIの実装
- DSLとは
- Domain Specific Language(ドメイン特化言語)
- ある分野に固有の語彙や語法を使用して事象を表現できるよう作られたプログラミング言語
- 大きく内部DSLと外部DSLに分類可能
- 内部DSL:
- 汎用のプログラミング言語の書き方を工夫して、見かけ上の構文を自然言語に近づけた言語
- 外部DSL:
- 汎用のプログラミング言語とはまったく別の構文を持ったDSL
DSLを使わない記述の場合、以下のようにコンパニオンオブジェクトを定義します。
object JsonController {
implicit val usersRowWritesFormat = new Writes[UsersRow] {
def writes(user: UsersRow): JsValue = {
Json.obj(
"id" -> user.id,
"name" -> user.name,
"companyId" -> user.companyId
)
}
}
}
これをJsonController.scala
に追加し、JsonController
のlist
メソッドを実装します。
そして、curl -XGET http://localhost:9000/json/list
でユーザ一覧のJSONを取得するのですが、以下のエラーが出てしまいました。
[error] type mismatch;
[error] found : Seq[models.Tables.Users#TableElementType]
[error] (which expands to) Seq[models.Tables.UsersRow]
[error] required: play.api.libs.json.Json.JsValueWrapper
[error] Note: implicit value usersRowWritesFormat is not applicable here because it comes after the application point and it lacks an explicit result type
[error] Ok(Json.obj("users" -> users))
[error] ^
また打ち間違えでもしたかと思ったのですが、確認してみても打ち間違いはありませんでした。
原因は、コンパニオンオブジェクトを記述する位置でした。JsonController
クラスの下に記述していたのを、上に記述するようにしたところ、エラーは出なくなりました。
ググってもわからず途方に暮れていたのですが、GitHubに公開されているソースコードを確認して気づくことができました。
暗黙の型変換の定義の結果型を省略した場合、定義より前で型変換を行うことができないため、コンパイルエラーになっていたようです。
詳しくはこちら。
ユーザ登録・更新APIの実装
特になし
ユーザ削除APIの実装
特になし