Spark Framework で非常に簡単にWebアプリケーション開発を開始できるということは、多くの記事でご覧になれると思います。さて、実際のWeb開発を行うには、さらにデータベースへ接続したり、JSONを返してAPIを作成したり、さらにサーバサイドレンダリングを行うならテンプレートエンジンが必要です。
このようなコンポーネントを組み合わせて開発する上で、実際にどのようなライブラリを組み合わせればよいのかというあたりを紹介したいと思います。
Guice
Java 8 のラムダ式で簡単に Route
が書けるとはいえ、すべてを main に書くのはつらいものがあります。トランザクションなどを含む少し長めの処理は、 Java 7 時代に戻って Route
を実装したクラスを書くのが賢明でしょう。
しかし、ラムダ式の部分を Route
クラスとして実装するとなると、キャプチャとして解決できていた変数は全てコンストラクタの引数として渡さなくてはいけません。これは非常に面倒です。そこで、 Route
に依存するオブジェクトを DI で解決することにしましょう。
有名な DI フレームワークとしては Spring がありますが、 Spark Framework と一緒に使うには少しおおげさです。それならそのまま Spring Boot を利用した方が素直でしょう。また、 Spring は Map<String, Object>
的な名前による DI を基本としているのに対して、 Guice は Map<Class, Object>
が基本なので、 IDE が名前を見つけられてリファクタリングがしやすいコードになる点が個人的には好みです。あと設定も Guice の方がわかりやすいと感じる人が多いのではないでしょうか。
args4j
コマンドラインを解析するライブラリはいくつかありますが、その中でも args4j は一番親切なオプションを作れる気がします。似たようなツールに JCommander や JOpt がありますが、どれか好きなのを使えば良いかと思います。
Lombok の @Data
で getter/setter を作成し、 Guice
の toInstance
で bind
すれば、アプリケーション全体の設定として各コンポーネントで共有することができます。さらにオプションを yml なんかで書けるようにすると今風ですが、とりあえずは envsubst
と xargs
で十分です。
Sql2o
データベースの操作には、 Spark Framework のチュートリアル に習って、 Sql2o を利用します。 args4j で取得した JDBC URL の設定によって Guice で DAO の bind を切り替えていれば、非標準の SQL を書いてしまうのもそれほど怖くはありません。そもそもマイクロサービスの思想的にも、2人週程度の工数で作り直せないレベルのものを作るべきではありません。
SQL なんて人の書くものではないという方は、 Hibernate や jOOQ あたりが選択肢に入ってくると思います。
2016/10/14 追記: HikiriCP との組み合わせも良いと思います。
Gson
JSON の Serialize/Deserialize には、 Jackson と Gson の選択肢がありますが、どうやら
小さめのJSONなら、GSONの方が速いらしい です。 Spark Framework のドキュメントでも Gson を紹介していますので、素直に Gson を使うことにします。もし作製した後でパフォーマンスの良い方を選択したいのであれば、 Adapter となるオブジェクトを作成し、 Guice に切り替えてもらいましょう。
Closure Templates
Closrue Templates は Java と JavaScript の両方から利用できるテンプレートエンジンです。 {{ mustache }} も様々な言語から利用できますが、 i18n 対応のあたりまで考えるとこちらの方が機能的にありがたいです。
最後に文字列にすればよいので、 Closure Templates をそのまま利用しても良いのですが、サーバを起動したまま変更を検知してテンプレートの再コンパイルを行うライブラリ を書きましたのでご活用ください。
まとめ
- GuiceのシンプルなDIで各コンポーネント間の依存関係を解決します
- Sql2oは
java.sql
のラッパーとして十分な機能を提供しています - APIに用いられる程度のサイズであれば、Jackson以外にGsonも悪くないの選択肢だと思います
- Closure Templatesを利用すると、JavaでもJavaScriptでも利用可能なテンプレートを作成できます
Spark Frameworkを用いたパターンの一つとして参考にしていただければと思います。