Lagomを試してみるシリーズ第三回です。今回はLagomでイミュータブルなデータクラスを作る方法について見ていきたいと思います。Lagomの本質にたどり着くにはまだまだ時間がかかりそうですw
Lagomのドキュメントを読んでいると以下のようなアノテーションてんこ盛りのインターフェースが登場します。
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.lightbend.lagom.javadsl.immutable.ImmutableStyle; import org.immutables.value.Value; @Value.Immutable @ImmutableStyle @JsonDeserialize(as = ItemId.class) @JsonSerialize(as = ItemId.class) public interface AbstractItemId { @Value.Parameter long orderId(); @Value.Parameter long itemId(); }
JSON関連はひとまず置いておいて、Immutablesのアノテーションを使ってイミュータブルなデータクラスを作っているようです。ちなみにImmutablesというのはJava用のライブラリでアノテーションプロセッサでインターフェースからコンパイル時にデータクラスを自動生成するというものです。
Immutablesを使うにはbuild.sbt
のhelloworld-apiプロジェクトの設定を以下のように編集します。
lazy val helloworldApi = project("helloworld-api") .settings( version := "1.0-SNAPSHOT", libraryDependencies ++= Seq( lagomJavadslApi, lagomJavadslImmutables // これを追加 ) )
前回作成したHelloId
をImmutablesを使ってイミュータブルなデータクラスにしてみます。
import com.lightbend.lagom.javadsl.immutable.ImmutableStyle; import org.immutables.value.Value; @ImmutableStyle @Value.Immutable public interface AbstractHelloId { @Value.Parameter String area(); @Value.Parameter String name(); }
アノテーションを付与するだけでなく、以下のような注意点があります。
- クラスではなくインターフェースにすること
- インターフェース名を
Abstract + クラス名
にすること - プロパティはメソッドとして定義すること
インターフェース名はAbstractHelloId
ですが、データクラスを使う側ではHelloId
で使うことができます。
@Override public ServiceCall<HelloId, NotUsed, String> hello() { return (id, request) -> completedFuture("Hello, " + id.name() + " in " + id.area() + "!"); }
なお、IntelliJではこのままだとアノテーションプロセッサで生成されるHelloId
クラスを認識することができません。調べてみたところ、HelloId.java
はtarget/scala-2.11/classes
ディレクトリに生成されていたので、プロジェクトの設定でこのディレクトリをソースパスに追加することで認識できるようになりました。