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

    View full-size slide

  2. Agenda
    おしながき
    ▸ Kotlin Serialization の紹介
    ▸ 既存 Seriailzation ⼿手法との違い
    ▸ Kotlin Serialization の設計思想
    ▸ ロードマップ
    2

    View full-size slide

  3. ここでは Java, Kotlin の話に限ります
    Serialization
    ▸ オブジェクトの構造や状態を primitives (e.g. Byte列列) に変換すること
    ▸ この⽂文脈では直列列化と訳されることが多い
    ▸ 並列列性に関する⽂文脈では逐次化と訳され、明確に区別される
    ▸ これ以上は・・・
    3

    View full-size slide

  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

    View full-size slide

  5. ▸ https://kotlinconf.com/talks/video/2019/122351/
    5

    View full-size slide

  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"
    }

    View full-size slide

  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"
    }

    View full-size slide

  8. Gradle Example
    ことはじめ - Kotlin code
    ▸ 直列列化対象に annotation を付与
    8
    import kotlinx.serialization.Serializable
    @Serializable
    data class Event(
    val name: String
    )

    View full-size slide

  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" }
    }

    View full-size slide

  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" }
    }

    View full-size slide

  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 の⼒力力

    View full-size slide

  12. Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの?
    12

    View full-size slide

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





    13

    View full-size slide

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

    14

    View full-size slide

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

    15

    View full-size slide

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

    16

    View full-size slide

  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

    View full-size slide

  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 無し 有り 無し 有り

    View full-size slide

  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 無し 有り 無し 有り

    View full-size slide

  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 無し 有り 無し 有り

    View full-size slide

  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 無し 有り 無し 有り

    View full-size slide

  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 無し 有り 無し 有り

    View full-size slide

  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 無し 有り 無し 有り

    View full-size slide

  24. Design of kotlin serialization
    Kotlin Serialization の構成員
    ▸ A compiler plugin
    ▸ Runtime ライブラリ
    ▸ Serializer
    ▸ Formatter
    ▸ Encoder / Decoder
    24

    View full-size slide

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

    View full-size slide

  26. Design of kotlin serialization
    Encoder と Decoder って?
    ▸ Encoder
    ▸ Serializer から Kotlin Primitives を受け取り Serialization の中間表現へ
    ▸ Decoder
    ▸ Serialization の中間表現を読み取り、Kotlin Primitives にしてSerializer へ
    ▸ 普通は⾃自分たちでは実装しない
    ▸ Multiplatform 対応の関係で中間表現を挟んでいる
    26

    View full-size slide

  27. Design of kotlin serialization
    Serializer と Formatter で考えきゃいけない点
    ▸ 最終的に出⼒力力フォーマットの表現⼒力力が限界点
    ▸ e.g. json で Polymorphism をどう表現する?
    ▸ A. type 名も json string に吐き出してる
    ▸ 後⽅方互換
    ▸ 順番に依存するフォーマットの場合は?
    ▸ Android なら難読化が絡むものをどうする?
    27

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

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

    View full-size slide

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

    View full-size slide