Lagomを試してみるシリーズ第4回です。今回はサービスの入力・出力としてJSONを使う方法を試してみました。
基本的にはサービスのRequestやResponseにJavaクラスを指定しておけば自動的にJacksonでJSONとのデシリアライズ、シリアライズを行ってくれるようです。
まずはリクエストを受け取るために以下のクラスを作成しました。Immutabesを使ったデータクラスです。@JsonDeserialize
アノテーションでImmutablesで生成された具象クラスでデシリアライズするよう設定しています。
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.lightbend.lagom.javadsl.immutable.ImmutableStyle; import org.immutables.value.Value; @ImmutableStyle @Value.Immutable @JsonDeserialize(as = HelloRequest.class) public interface AbstractHelloRequest { @Value.Parameter String area(); @Value.Parameter String name(); }
レスポンスを返すためのクラスも同様に作成します。@JsonDeserialize
の代わりに@JsonSerialize
アノテーションを使用しています。
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.lightbend.lagom.javadsl.immutable.ImmutableStyle; import org.immutables.value.Value; @ImmutableStyle @Value.Immutable @JsonSerialize(as = HelloResponse.class) public interface AbstractHelloResponse { @Value.Parameter String message(); }
サービスの定義を以下のようにします。RequestとResponseのところにImmutablesで生成されるデータクラスの具象型を指定しています。
public interface HelloService extends Service { ServiceCall<NotUsed, HelloRequest, HelloResponse> hello(); @Override default Descriptor descriptor() { // @formatter:off return named("helloservice").with( restCall(Method.GET, "/api/hello", hello()) ).withAutoAcl(true); // @formatter:on } }
サービスの実装はこんな感じ。
public class HelloServiceImpl implements HelloService { @Override public ServiceCall<NotUsed, HelloRequest, HelloResponse> hello() { return (id, request) -> { return completedFuture(HelloResponse.of( "Hello, " + request.name() + " in " + request.area() + "!" )); }; } }
動作確認してみます。
$ curl -i -H 'Content-Type: application/json' -XGET http://localhost:9000/api/hello -d '{"name": "Naoki", "area": "Japan"}' HTTP/1.1 200 OK Content-Length: 36 Content-Type: application/json; charset=utf-8 Date: Sat, 16 Apr 2016 17:04:18 GMT {"message":"Hello, Naoki in Japan!"}
JSONの使用については特に難しいところはなさそうです。