Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Serialization in Kotlin World

Serialization in Kotlin World

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

Matsuda Jumpei

January 17, 2020
Tweet

More Decks by Matsuda Jumpei

Other Decks in Programming

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