sbtのマルチプロジェクト構成によって関心事を分離する

こんにちは、id:katzchang / @katzchang です。

Zucks Ad Networkでは広告配信に使うWEB APIサーバを Scala で実装しています。当然、ビルドツールには sbt を使っています。で、いい感じに分離して設計するためにマルチプロジェクト構成にしたかったんですが、探し方が悪いのか、なかなか構成例が見つかりません…。そもそも ./build.sbt./project/Build.scala の二通りの構成定義があってググってもどっち向けの記述かよくわからなかったり。

ということで、実際に使っている定義を使って紹介しようと思います。

なぜマルチプロジェクト構成か?

Zucks Ad Networkでの広告配信サーバは現在、JSONデータを返すWEB APIサーバで動かしています。十分に低レイテンシかつ高スループットか、シンプルに実装しやすいかなどが検討され、フレームワークやプロトコルは様々なものが考えられます。しかし、それらは広告選択戦略とはあまり関係がありません。

つまり、広告選択戦略はコアドメイン、WEBアプリケーションはインタフェースと捉えることができます。それぞれを独立したライブラリとして実装することにより、保守性と試験性を確保するようにしています。

./project

project ディレクトリのファイル構成は↓な感じです。Build.scala で定義しています。

コアドメインである zgok-adserver-scala、および、支援ドメインである zgok-vltzgok-goat (どちらも広告効果を高めるためのサービスの開発コードです)は、 servlet-api には依存していません。すなわち、httpであることは完全に関心の外に置くことができます。Loggerも同様で、実装は logback-classic を使っていますが、コアドメイン・支援ドメインには感知させない構成にしています。

そうそう、WEBアプリケーションフレームワークとして、Servletを使っています。実績があり枯れている、シングルスタックである、コード例も多く実装も簡単、パフォーマンスも十分だというのが理由です。実運用でのサーブレットコンテナは Tomcat7 を利用しています。これ以上のパフォーマンスを出す最新のかっこいいフレームワーク・ミドルウェアは色々あるかもしれませんが、現状では十分動いているので、まぁよしとしましょうよ。仕事は他に沢山あるし。

他に細かいところとして、scala.concurrent.ExecutionContext を使った機能のテストが安定して動くように scala.concurrent.context.numThreads 等の値を明示していたり、共通的に使うdependencyをまとめて定義していたり、などなどの定義をしています。

まだ不自然なところがあるかもしれません。あるでしょう?もっとこう書くといいのに!っていうアイデアをお持ちの方は是非、コメント頂けたり、もしくは社内バーAJITOにビールを飲みに来て頂いたりとかすると、とてもいいと思います!!

ということで、ブックマークコメントやmentionなど、お待ちしておりますmm

実践テスト駆動開発 (Object Oriented SELECTION)

実践テスト駆動開発 (Object Oriented SELECTION)