始めに
ようやく最終回です。今回はエントリーポイントを定義し、DockerImage化を行います。
これまで##
構成##
- IntelliJ 2018
- Scala 2.12.5
- sbt 1.1.4
- Akka 2.5.11
- AkkaHttp 10.1.0
- Slick 3.2.3
- Scalaz 7.2.19
成果物##
Entry Point
単純にこれまで作ってきた物を組み立てるだけです。
HttpAppのhostを「0.0.0.0」としているのはDocker経由でアクセスできるようにするためです。Lightweight docker containers for Scala appsを参考にしています。
package todo.api
import scala.concurrent.ExecutionContext
import scala.concurrent.duration._
import akka.actor.ActorSystem
import akka.util.Timeout
import slick.jdbc.H2Profile.api._
import todo.api.repository.{TodoRepository, TodoRepositoryImpl}
// メインエントリポイント
object Main extends App {
import todo.api.actor._
implicit val system: ActorSystem = ActorSystem("todo-api")
implicit val executor: ExecutionContext = system.dispatcher
implicit val timeout: Timeout = Timeout(5.seconds)
// レポジトリ定義
val db = Database.forConfig("todo-slick-db")
val todoRepository: TodoRepository = TodoRepositoryImpl(db)
// アクター定義
val todoSupervisor = system.actorOf(TodoSupervisor.props(3, 30.seconds))
todoSupervisor ! TodoSupervisor.RegistrationCommand(TodoActor.props(todoRepository))
// ルート定義
val todoRoutes = TodoRoutes(todoSupervisor)
val todoAPIServer = TodoAPIServer(todoRoutes)
todoAPIServer.startServer("0.0.0.0", 8000, system)
}
以上、実際にsbtでrunコマンドを実行してみて、curl等で動作確認できれば完成です。
DockerImage化
sbt docker:publishLocalでtarget/docker/stage配下にDockerfileが作成され、ローカルのDockerにDockerImageが作成されます。
終わりに
全5回は長かった・・・。元も子もないこと言ってしまうと、このレベルのAPIとかならGoとかで書いた方がたぶん楽だとは思う。もっと複雑なものを書くのに使った方が良い。
以下もろもろの感想
Scalaについて##
モナドを使った関数合成が綺麗に書けたりすると感動するが、オブジェクト指向的に扱う部分と関数型プログラミング的に扱う部分を上手いこと線引きせんと苦しくなる。
アプリを書こうと思ったら副作用とは切り離せない部分もあると思う。今のところは関数型で行けるとこは頑張って、無理そうならあっさり諦める感じで書いてる。
Akkaについて##
アクターがメッセージ含めて型安全になれば完璧だと思う。DIの間にアクター(ActorRef)が挟まると不安になる。
トップレベルに近いアプリケーション層とかには最適だとは思う(Persistenceはまた別物)。
AkkaHttpについて##
AkkaHttpには特に文句ない。その内、ストリームも挑戦したい。
Slickについて##
ドキュメントが分かりづらいんですが・・・(自分だけでしょうか?)。
今回はH2に決め打ちして書いたけど、別のデータベースに切り替えられるようにドライバーを抽象化しようとすると割と面倒くさい。
HikariCPがたまに謎の警告を発したりするがまだよく分からん。