- 投稿日:2019-04-17T07:30:08+09:00
Kotlin Serialization事始め
はじめに
僕が神と崇めているJake Wharton氏(@JakeWharton)のGitHubを眺めていたら、 Kotlin Serialization なるものを使っていることが分かりました。神が使っているものだから、きっと我々下々の民に素晴らしい恩恵を与えるものに違いない
そう思い使い方を調べてみました。
Kotlin Serializationとは
Kotlin serialization consists of a compiler plugin, which automatically produces visitor code for classes, and runtime library, which uses generated code to serialize objects without reflection.
公式リポジトリの説明によると、『Kotlin Serializationはクラスのビジターコードを自動的に生成するコンパイラプラグインと、生成されたコードを使用してリフレクションなしでオブジェクトをシリアル化するランタイムライブラリで構成されている』そうです。はぁ
さらに、Kotlin Serializationは以下の機能を備えているそうです。
@Serializable
及び標準コレクションとしてマークされているKotlinクラスをサポート- JSON、CBOR及びProtobuf形式をサポート
- 同様のコードがJVM/JS/Nativeで機能するマルチプラットフォーム
要するに、Web APIなどのレスポンスをサービスで利用できる形式のオブジェクトに変換する、パーサのようなものかなと。JSONのパーサだと、GsonやMoshiなどが有名ですね。また、これらのパーサと比べて、リフレクションを使用していないため、動作が早いんだとか。ほほう。
導入
コンパイラプラグインをプロジェクトルートに追加します。
build.gradlebuildscript { ext.kotlin_version = '1.3.30' dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" } }なお、Kotlinのバージョンは
1.3.30
以上が必要とのことです。続いて、モジュールに依存関係とプラグインに関する追記をします。build.gradleapply plugin: 'kotlinx-serialization' repositories { maven { url "https://kotlin.bintray.com/kotlinx" } } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.11.0' }全ての追記が終わったら
Sync Project
を実行し、エラーが出ていなければOKです。使い方
以下のようなJSON形式の場合
repo.json{ "name": "dagger", "description": "A fast dependency injector for Android and Java. http://google.github.io/dagger", "language": "Java", "html_url": "https://github.com/google/dagger", "watchers_count": 563, "stargazers_count": 13294, "forks_count": 2672, "owner": { "login": "google", "avatar_url": "https://avatars1.githubusercontent.com/u/1342004?v=4" } }こんなモデルを作ります。
Repo.kt@Serializable data class Repo( val name: String, val description: String? = null, val language: String? = null, @SerialName("html_url") val url: String, @SerialName("watchers_count") val watchers: Int, @SerialName("stargazers_count") val stars: Int, @SerialName("forks_count") val forks: Int, val owner: Owner )Owner.kt@Serializable data class Owner( val login: String, @SerialName("avatar_url") val avatar: String )
@Serializable
アノテーションを付けたKotlinクラスがシリアライズの対象になります。@SerialName
アノテーションはJSONのキー名と違ったパラメータを紐づける場合に使います。その他のアノテーションは公式のドキュメントを参考にしてください。Gson/Moshiからの移行
Retrofit+GsonあるいはRetrofit+Moshiなどで、すでにAPIを叩く処理を実装している場合、Kotlin Serializationへの移行はできないのではないか?安心してください。神は我々を見捨てませんでした
Kotlin Serialization Converter
Retorfit向けにコンバータを用意してくれていたのです。このコンバータをGsonやMoshi同様に
Api.ktval contentType = MediaType.get("application/json") val retrofit = Retrofit.Builder() .baseUrl("https://example.com/") .addConverterFactory(Json.asConverterFactory(contentType)) .build()とすれば、Kotlin Serializationが使えます。今後正式にRetrofitのプロジェクトに採用されるかもしれません。
まとめ
JSON以外にもパースできる形式があったり、独自のシリアライズを定義することもできるのですが、今回はひとまず概要のみで割愛させていただきました。導入に関しては、使用可能なKotlinバージョンの縛りはあるものの、GsonやMoshi同様にアノテーションで簡潔に書くことができました。導入コストも比較的低いのではないでしょうか。また、先述した動作速度の向上に関しても気になるところではあるので、時間がある時に他のパーサと比較してみたいと思います。今回はこのへんで。
参考文献
- Kotlin Serialization: https://github.com/Kotlin/kotlinx.serialization