LoginSignup
18

More than 5 years have passed since last update.

Play 2.3.xから2.4.x、Slick 2.xから3.1.xへの移行

Last updated at Posted at 2015-12-19

Play Java 歴 1 年くらいの私が、最近、プロジェクトで、Play Scala、Slickのバージョンアップを行いました。マイグレーションを行う方が、事前に知っておいた方が良いことについて記しておきます。なお、ここに記載されていることが全てではありませんので、マイグレーションガイドを参照ください。

Play 2.4.x への以降

移行の詳細については、マイグレーションガイドを参照。

ビルド方法の変更

project/plugins.sbt にあるPlayを以下に更新します。

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.0")

Play 2.4 の対応 sbt バージョンは 0.13.8 です。project/build.properties を更新しましょう。

sbt.version=0.13.8

Javaは8のみサポート

6と7はサポート対象外になり、6または7でビルドしようとするとエラーになるようです。

Dependency Injectionのサポート

3.0 でグローバルな状態管理を完全に廃止することを目標にDIの導入を行っているようです。2.4から Guiceというライブラリを使ったDIをデフォルトでサポートし始めたようです。DIの詳細はドキュメントを参照。

対応する場合、まずbuild.sbtにルートジェネレータとして、DIに対応版を使うことを明記。

routesGenerator := InjectedRoutesGenerator

DI 対応の目印で conf/routes の Controller のメソッド名に @ をつけます。

GET        /some/path           @controllers.Application.index
  • DIのを使うことは @Inject で明記します。@injectJSR330 で決められた DI 用のアノテーション。
  • 共通に DI を使う用途は、後述のメッセージ国際化対応(messagesApi: MessagesApi)、DB の設定(dbConfigProvider: DatabaseConfigProvider)です。
class Application @Inject() (dbConfigProvider: DatabaseConfigProvider, messagesApi: MessagesApi) extends Controller with I18nSupport {

なお、コントローラを object(シングルトンオブジェクト)としていた場合、今後はclassにし、かつ @Singleton をつけることで、引き続きシングルトンとして扱うことが可能です。

@Singleton
class YoutSingletonClass @Inject(yourParameter: YourClass) {

国際化APIへの対応

Internationalization API が導入されました。ビューに表示するメッセージは言語ごとに設定ファイルとして用意し、 play.api.i18n.Messages としてコントローラやビューに渡すようになりました。詳細はドキュメント参照。

DIの仕組みでviewに注入するため、viewの先頭にmessageの宣言が必要です。

(implicit messages: Messages)

Controllerも messagesApi: play.api.i18n.Messages を渡すように修正が必要。

class Application @Inject() (dbConfigProvider: DatabaseConfigProvider, messagesApi: MessagesApi) extends Controller with I18nSupport {

また、conf/application.confのアプリケーション言語設定もi18nの方を使うように修正。

play.i18n.langs = [ "en" ]

Slick 3.0 への移行

詳細は Slick のマイグレーションガイドを参照。

buid.sbtの変更

  • play-slick のバージョンを変更します。
  • evolutions は別モジュールに切りだされたそうです。利用する場合は "evolutions"(ORM 共通)と "play-slick-evolutions"(Slickのevolutions)が必要です。
libraryDependencies ++= Seq(
  ...
  evolutions,
  "com.typesafe.play" % "play-slick_2.11" % "1.1.1",
  "com.typesafe.play" %% "play-slick-evolutions" % "1.1.1",
  ...
)

evolutiuonを止めたい場合は、conf/application.confに以下を設定。プロパティ名が変更されている点に注意。

play.evolutions.enabled=false

DBの設定

slick を使う場合、application.conf の設定名が変更。プロパティ名が変更されている点に注意。

slick.dbs.default.driver="slick.driver.H2Driver$"
slick.dbs.default.db.driver=org.h2.Driver
slick.dbs.default.db.url="jdbc:h2:mem:play"
slick.dbs.default.db.user=sa
slick.dbs.default.db.password=""

Slick ドライバの自動検出

これまでは以下の import で特定のドライバ用のAPIをインポートしていましたが、この方法は廃止されました。

import play.api.db.slick.Config.driver.simple._.

これからは application.conf で設定したものをフレームワークが自動検出し、DI で注入するようになりました。import driver.api._ の箇所で設定したドライバの API が利用できるようになります。

class Application @Inject() (dbConfigProvider: DatabaseConfigProvider, messagesApi: MessagesApi) extends Controller with I18nSupport {
  val dbConfig = dbConfigProvider.get[JdbcProfile]

  import dbConfig._
  import driver.api._

非同期クエリ実行のサポート

2.x系で使われていたDBAction、DBSessionRequest、DB.withSessionなどのAPIが廃止されました。

このドキュメントにあるように今後は、db.runというAPIを使います。これは Future を返すメソッドです。DB のクエリが非同期化され、コントローラのレスポンス部分も非同期化(Futureを返す)ようになっている点に注目。
例えば、あるまとまった処理を小分けてし、非同期処理し、結果がまとまったら返すみたいなことができ、スケールアウトさせることが容易になったといえます。

def index(name: String) = Action.async { implicit request =>
  val resultingUsers: Future[Seq[User]] = dbConfig.db.run(Users.filter(_.name === name).result)
  resultingUsers.map(users => Ok(views.html.index(users)))
}

以上です。本記事が、これからマイグレーションを行う方にとって参考になりましたら、幸いです。もし記事の内容で、気になる点、間違いなどありましたら、コメントいただけると嬉しいです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18