Serialization in Kotlin World

Serialization in Kotlin World

shibuya.apk#38
KotlinConf 2019 で発表された Design of Kotlin Serialization をベースに、kotlinx.serialization を紹介しました

D4133d8efb46ae872d7a563b619bfc83?s=128

Matsuda Jumpei

January 17, 2020
Tweet

Transcript

  1. Serialization in Kotlin World shibuya.apk #38 1

  2. Agenda おしながき ▸ Kotlin Serialization の紹介 ▸ 既存 Seriailzation ⼿手法との違い

    ▸ Kotlin Serialization の設計思想 ▸ ロードマップ 2
  3. ここでは Java, Kotlin の話に限ります Serialization ▸ オブジェクトの構造や状態を primitives (e.g. Byte列列)

    に変換すること ▸ この⽂文脈では直列列化と訳されることが多い ▸ 並列列性に関する⽂文脈では逐次化と訳され、明確に区別される ▸ これ以上は・・・ 3
  4. https://github.com/Kotlin/kotlinx.serialization Kotlin Serialization ▸ Kotlin 公式による直列列化⽅方式 (framework) ▸ Kotlin オブジェクトを柔軟に扱える

    ▸ Optional types, data classes, sealed classes, default arguments ... ▸ 現時点では experimental (coming soon!) ▸ 今までは幾度か後⽅方互換のない変更更もあったけど・・・ ▸ KotlinConf 2019 で担当者から設計や構想についての発表があった 4
  5. ▸ https://kotlinconf.com/talks/video/2019/122351/ 5

  6. Gradle Example ことはじめ - Gradle ▸ Compier plugin を追加 ▸

    Runtime ライブラリを追加 (Kotlin version 等とは別なので注意) 6 dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0" } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" }
  7. Gradle Example ことはじめ - Gradle ▸ Compier plugin を追加 ▸

    Runtime ライブラリを追加 (Kotlin version 等とは別なので注意) 7 dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0" } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" }
  8. Gradle Example ことはじめ - Kotlin code ▸ 直列列化対象に annotation を付与

    8 import kotlinx.serialization.Serializable @Serializable data class Event( val name: String )
  9. Gradle Example ことはじめ - Kotlin code ▸ 好みの formatter (e.g.

    json) を選んで、 9 import kotlinx.serialization.Serializable @Serializable data class Event( val name: String ) fun main() { val formatter = Json(JsonConfiguration.Stable) val event = Event(name = "shibuya.apk") val jsonStr = formatter.stringify(Event.serializer(), event) println(jsonStr) // { "name" : "shibuya.apk" } }
  10. Gradle Example ことはじめ - Kotlin code ▸ 好みの formatter (e.g.

    json) を選んで、変換 10 import kotlinx.serialization.Serializable @Serializable data class Event( val name: String ) fun main() { val formatter = Json(JsonConfiguration.Stable) val event = Event(name = "shibuya.apk") val jsonStr = formatter.stringify(Event.serializer(), event) println(jsonStr) // { "name" : "shibuya.apk" } }
  11. Gradle Example ことはじめ - Kotlin code ▸ compiler plugin が

    serialize (deserialize) ⽅方法を⾃自動⽣生成 11 import kotlinx.serialization.Serializable @Serializable data class Event( val name: String ) fun main() { val formatter = Json(JsonConfiguration.Stable) val event = Event(name = "shibuya.apk") val jsonStr = formatter.stringify(Event.serializer(), event) println(jsonStr) // { "name" : "shibuya.apk" } } compiler plugin の⼒力力
  12. Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? 12

  13. Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? ▸ < ノー ▸ ▸

    ▸ ▸ ▸ 13
  14. Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? ▸ < ノー ▸ Kotlin

    ⾔言語仕様を思う存分利利⽤用した直列列化 framework ▸ java.lang.Serializable の Kotlin 実装ではない ▸ android.os.Parcelable の Multiplatform ⽤用実装ではない ▸ みんな⼤大好き Json のためだけに存在するわけではない ▸ 14
  15. Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? ▸ < ノー ▸ Kotlin

    ⾔言語仕様を思う存分利利⽤用した直列列化 framework ▸ java.lang.Serializable の Kotlin 実装ではない ▸ でも Kotlin Serialization で実現することはできる ▸ android.os.Parcelable の Multiplatform ⽤用実装ではない ▸ みんな⼤大好き Json のためだけに存在するわけではない ▸ 15
  16. Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? ▸ < ノー ▸ Kotlin

    ⾔言語仕様を思う存分利利⽤用した直列列化 framework ▸ java.lang.Serializable の Kotlin 実装ではない ▸ でも Kotlin Serialization で実現することはできる ▸ android.os.Parcelable の Multiplatform ⽤用実装ではない ▸ でも Kotlin Serialization の仕組みの中で Multiplatform Parcelable は実現できる ▸ みんな⼤大好き Json のためだけに存在するわけではない ▸ 16
  17. Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? ▸ < ノー ▸ Kotlin

    ⾔言語仕様を思う存分利利⽤用した直列列化 framework ▸ java.lang.Serializable の Kotlin 実装ではない ▸ でも Kotlin Serialization で実現することはできる ▸ android.os.Parcelable の Multiplatform ⽤用実装ではない ▸ でも Kotlin Serialization の仕組みの中で Multiplatform Parcelable は実現できる ▸ みんな⼤大好き Json のためだけに存在するわけではない ▸ でも Kotlin Serialization で Json を出⼒力力することも、読み込むこともできる 17
  18. ※ 良い / 悪い という⽐比較ではないことに注意 Kotlin Serialization といくつかの直列列化⽅方式の⽐比較 18 Java

    Serializable Android Parcelable Gson (特殊例例) Kotlin Serialization Platform JVM Android JVM Multiplatform 直列列化⽅方針 Reflection ユーザ定義 (FIFO W/R 制約) Reflection またはユーザ定義 ユーザ定義 (プリセット有り) ⼊入⼒力力制約 Interface Interface + 型クラス 無し 無し 出⼒力力制約 無し Parcel e.g. Bundle Json 無し (Formatterに依存) ⾃自動⽣生成 N/A (Reflection) 有り (Kotlin のみ) 有り (ただし3rd party) 有り Kotlin Support 無し 有り 無し 有り
  19. ※ 良い / 悪い という⽐比較ではないことに注意 Kotlin Serialization といくつかの直列列化⽅方式の⽐比較 19 Java

    Serializable Android Parcelable Gson (特殊例例) Kotlin Serialization Platform JVM Android JVM Multiplatform 直列列化⽅方針 Reflection ユーザ定義 (FIFO W/R 制約) Reflection またはユーザ定義 ユーザ定義 (プリセット有り) ⼊入⼒力力制約 Interface Interface + 型クラス 無し 無し 出⼒力力制約 無し Parcel e.g. Bundle Json 無し (Formatterに依存) ⾃自動⽣生成 N/A (Reflection) 有り (Kotlin のみ) 有り (ただし3rd party) 有り Kotlin Support 無し 有り 無し 有り
  20. ※ 良い / 悪い という⽐比較ではないことに注意 Kotlin Serialization といくつかの直列列化⽅方式の⽐比較 20 Java

    Serializable Android Parcelable Gson (特殊例例) Kotlin Serialization Platform JVM Android JVM Multiplatform 直列列化⽅方針 Reflection ユーザ定義 (FIFO W/R 制約) Reflection またはユーザ定義 ユーザ定義 (プリセット有り) ⼊入⼒力力制約 Interface Interface + 型クラス 無し 無し 出⼒力力制約 無し Parcel e.g. Bundle Json 無し (Formatterに依存) ⾃自動⽣生成 N/A (Reflection) 有り (Kotlin のみ) 有り (ただし3rd party) 有り Kotlin Support 無し 有り 無し 有り
  21. ※ 良い / 悪い という⽐比較ではないことに注意 Kotlin Serialization といくつかの直列列化⽅方式の⽐比較 21 Java

    Serializable Android Parcelable Gson (特殊例例) Kotlin Serialization Platform JVM Android JVM Multiplatform 直列列化⽅方針 Reflection ユーザ定義 (FIFO W/R 制約) Reflection またはユーザ定義 ユーザ定義 (プリセット有り) ⼊入⼒力力制約 Interface Interface + 型クラス 無し 無し 出⼒力力制約 無し Parcel e.g. Bundle Json 無し (Formatterに依存) ⾃自動⽣生成 N/A (Reflection) 有り (Kotlin のみ) 有り (ただし3rd party) 有り Kotlin Support 無し 有り 無し 有り
  22. ※ 良い / 悪い という⽐比較ではないことに注意 Kotlin Serialization といくつかの直列列化⽅方式の⽐比較 22 Java

    Serializable Android Parcelable Gson (特殊例例) Kotlin Serialization Platform JVM Android JVM Multiplatform 直列列化⽅方針 Reflection ユーザ定義 (FIFO W/R 制約) Reflection またはユーザ定義 ユーザ定義 (プリセット有り) ⼊入⼒力力制約 Interface Interface + 型クラス 無し 無し 出⼒力力制約 無し Parcel e.g. Bundle Json 無し (Formatterに依存) ⾃自動⽣生成 N/A (Reflection) 有り (Kotlin のみ) 有り (ただし3rd party) 有り Kotlin Support 無し 有り 無し 有り
  23. ※ 良い / 悪い という⽐比較ではないことに注意 Kotlin Serialization といくつかの直列列化⽅方式の⽐比較 23 Java

    Serializable Android Parcelable Gson (特殊例例) Kotlin Serialization Platform JVM Android JVM Multiplatform 直列列化⽅方針 Reflection ユーザ定義 (FIFO W/R 制約) Reflection またはユーザ定義 ユーザ定義 (プリセット有り) ⼊入⼒力力制約 Interface Interface + 型クラス 無し 無し 出⼒力力制約 無し Parcel e.g. Bundle Json 無し (Formatterに依存) ⾃自動⽣生成 N/A (Reflection) 有り (Kotlin のみ) 有り (ただし3rd party) 有り Kotlin Support 無し 有り 無し 有り
  24. Design of kotlin serialization Kotlin Serialization の構成員 ▸ A compiler

    plugin ▸ Runtime ライブラリ ▸ Serializer ▸ Formatter ▸ Encoder / Decoder 24
  25. Design of kotlin serialization Serializer と Formatter ▸ Serializer ▸

    Kotlin オブジェクトを受け取って、Encoder にどうデータを詰めて、Decoder からどう取り出すのかを担当 ▸ オブジェクトフィールド外の情報等を⾜足すなどの場合は⾃自前で書く ▸ Formatter ▸ Serializer を利利⽤用し、parse/format したり (e.g. json string -> Kotlin オブ ジェクト) ▸ patch メソッドを実装すると migration 的なものを実現できる 25
  26. Design of kotlin serialization Encoder と Decoder って? ▸ Encoder

    ▸ Serializer から Kotlin Primitives を受け取り Serialization の中間表現へ ▸ Decoder ▸ Serialization の中間表現を読み取り、Kotlin Primitives にしてSerializer へ ▸ 普通は⾃自分たちでは実装しない ▸ Multiplatform 対応の関係で中間表現を挟んでいる 26
  27. Design of kotlin serialization Serializer と Formatter で考えきゃいけない点 ▸ 最終的に出⼒力力フォーマットの表現⼒力力が限界点

    ▸ e.g. json で Polymorphism をどう表現する? ▸ A. type 名も json string に吐き出してる ▸ 後⽅方互換 ▸ 順番に依存するフォーマットの場合は? ▸ Android なら難読化が絡むものをどうする? 27
  28. Design of kotlin serialization Serializer や Formatter の実装例例 ▸ Runtime

    ライブラリに含まれるもの ▸ JSON, Protocol Buffer, CBOR ▸ 3rd party 実装 ▸ Avlo, Bson, XML, YAML ▸ ref: kotlinx.serialization リポジトリの formats/README.md 28
  29. Future state Kotlin 1.4 が転換期 ▸ ~ Kotlin 1.4 ▸

    Inline class がサポートされる予定(絶賛進⾏行行中) ▸ IO streaming (w/ kotlin-io : Marshaling) やパフォーマンスチューニング ▸ (near) Kotlin 1.4 ~ ▸ Stable に ▸ Community-driven な直列列化フォーマットの growth 29
  30. さいごに Kotlin Serialization を Android 開発 on Production で使うことについて ▸

    (個⼈人的には) もう使っていいと思う ▸ もちろん Multiplatform Parcelable にする必要はない ▸ Inline class は⾃自前で Serializer を定義すればよい ▸ 後⽅方互換については、永続化さえしなければ特段問題は発⽣生しないはず ▸ Json しか使わないなら Moshi (+Kotshi) を選択肢に⼊入れましょう ▸ ※ 修正漏漏れで発表時は Kotshi と書いていましたが、Moshi です 30
  31. Thanks おしまい ▸ Jumpei Matsuda @red_fat_daruma (jmatsu on GitHub) ▸

    DeployGate で働きながら Alp でお⼿手伝い ▸ DroidKaigi 2020 スタッフ ▸ 公式アプリレビュワー ▸ 発表者 ▸ KotlinConf 2019、コペンハーゲン(のビールと飯)の話もしましょう 31