Serialization in Kotlin World
by
Matsuda Jumpei
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
Serialization in Kotlin World shibuya.apk #38 1
Slide 2
Slide 2 text
Agenda おしながき ▸ Kotlin Serialization の紹介 ▸ 既存 Seriailzation ⼿手法との違い ▸ Kotlin Serialization の設計思想 ▸ ロードマップ 2
Slide 3
Slide 3 text
ここでは Java, Kotlin の話に限ります Serialization ▸ オブジェクトの構造や状態を primitives (e.g. Byte列列) に変換すること ▸ この⽂文脈では直列列化と訳されることが多い ▸ 並列列性に関する⽂文脈では逐次化と訳され、明確に区別される ▸ これ以上は・・・ 3
Slide 4
Slide 4 text
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
Slide 5
Slide 5 text
▸ https://kotlinconf.com/talks/video/2019/122351/ 5
Slide 6
Slide 6 text
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" }
Slide 7
Slide 7 text
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" }
Slide 8
Slide 8 text
Gradle Example ことはじめ - Kotlin code ▸ 直列列化対象に annotation を付与 8 import kotlinx.serialization.Serializable @Serializable data class Event( val name: String )
Slide 9
Slide 9 text
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" } }
Slide 10
Slide 10 text
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" } }
Slide 11
Slide 11 text
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 の⼒力力
Slide 12
Slide 12 text
Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? 12
Slide 13
Slide 13 text
Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? ▸ < ノー ▸ ▸ ▸ ▸ ▸ 13
Slide 14
Slide 14 text
Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? ▸ < ノー ▸ Kotlin ⾔言語仕様を思う存分利利⽤用した直列列化 framework ▸ java.lang.Serializable の Kotlin 実装ではない ▸ android.os.Parcelable の Multiplatform ⽤用実装ではない ▸ みんな⼤大好き Json のためだけに存在するわけではない ▸ 14
Slide 15
Slide 15 text
Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? ▸ < ノー ▸ Kotlin ⾔言語仕様を思う存分利利⽤用した直列列化 framework ▸ java.lang.Serializable の Kotlin 実装ではない ▸ でも Kotlin Serialization で実現することはできる ▸ android.os.Parcelable の Multiplatform ⽤用実装ではない ▸ みんな⼤大好き Json のためだけに存在するわけではない ▸ 15
Slide 16
Slide 16 text
Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? ▸ < ノー ▸ Kotlin ⾔言語仕様を思う存分利利⽤用した直列列化 framework ▸ java.lang.Serializable の Kotlin 実装ではない ▸ でも Kotlin Serialization で実現することはできる ▸ android.os.Parcelable の Multiplatform ⽤用実装ではない ▸ でも Kotlin Serialization の仕組みの中で Multiplatform Parcelable は実現できる ▸ みんな⼤大好き Json のためだけに存在するわけではない ▸ 16
Slide 17
Slide 17 text
Kotlin Serialization は既存直列列化⼿手法の Kotlin 実装なの? ▸ < ノー ▸ Kotlin ⾔言語仕様を思う存分利利⽤用した直列列化 framework ▸ java.lang.Serializable の Kotlin 実装ではない ▸ でも Kotlin Serialization で実現することはできる ▸ android.os.Parcelable の Multiplatform ⽤用実装ではない ▸ でも Kotlin Serialization の仕組みの中で Multiplatform Parcelable は実現できる ▸ みんな⼤大好き Json のためだけに存在するわけではない ▸ でも Kotlin Serialization で Json を出⼒力力することも、読み込むこともできる 17
Slide 18
Slide 18 text
※ 良い / 悪い という⽐比較ではないことに注意 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 無し 有り 無し 有り
Slide 19
Slide 19 text
※ 良い / 悪い という⽐比較ではないことに注意 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 無し 有り 無し 有り
Slide 20
Slide 20 text
※ 良い / 悪い という⽐比較ではないことに注意 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 無し 有り 無し 有り
Slide 21
Slide 21 text
※ 良い / 悪い という⽐比較ではないことに注意 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 無し 有り 無し 有り
Slide 22
Slide 22 text
※ 良い / 悪い という⽐比較ではないことに注意 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 無し 有り 無し 有り
Slide 23
Slide 23 text
※ 良い / 悪い という⽐比較ではないことに注意 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 無し 有り 無し 有り
Slide 24
Slide 24 text
Design of kotlin serialization Kotlin Serialization の構成員 ▸ A compiler plugin ▸ Runtime ライブラリ ▸ Serializer ▸ Formatter ▸ Encoder / Decoder 24
Slide 25
Slide 25 text
Design of kotlin serialization Serializer と Formatter ▸ Serializer ▸ Kotlin オブジェクトを受け取って、Encoder にどうデータを詰めて、Decoder からどう取り出すのかを担当 ▸ オブジェクトフィールド外の情報等を⾜足すなどの場合は⾃自前で書く ▸ Formatter ▸ Serializer を利利⽤用し、parse/format したり (e.g. json string -> Kotlin オブ ジェクト) ▸ patch メソッドを実装すると migration 的なものを実現できる 25
Slide 26
Slide 26 text
Design of kotlin serialization Encoder と Decoder って? ▸ Encoder ▸ Serializer から Kotlin Primitives を受け取り Serialization の中間表現へ ▸ Decoder ▸ Serialization の中間表現を読み取り、Kotlin Primitives にしてSerializer へ ▸ 普通は⾃自分たちでは実装しない ▸ Multiplatform 対応の関係で中間表現を挟んでいる 26
Slide 27
Slide 27 text
Design of kotlin serialization Serializer と Formatter で考えきゃいけない点 ▸ 最終的に出⼒力力フォーマットの表現⼒力力が限界点 ▸ e.g. json で Polymorphism をどう表現する? ▸ A. type 名も json string に吐き出してる ▸ 後⽅方互換 ▸ 順番に依存するフォーマットの場合は? ▸ Android なら難読化が絡むものをどうする? 27
Slide 28
Slide 28 text
Design of kotlin serialization Serializer や Formatter の実装例例 ▸ Runtime ライブラリに含まれるもの ▸ JSON, Protocol Buffer, CBOR ▸ 3rd party 実装 ▸ Avlo, Bson, XML, YAML ▸ ref: kotlinx.serialization リポジトリの formats/README.md 28
Slide 29
Slide 29 text
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
Slide 30
Slide 30 text
さいごに Kotlin Serialization を Android 開発 on Production で使うことについて ▸ (個⼈人的には) もう使っていいと思う ▸ もちろん Multiplatform Parcelable にする必要はない ▸ Inline class は⾃自前で Serializer を定義すればよい ▸ 後⽅方互換については、永続化さえしなければ特段問題は発⽣生しないはず ▸ Json しか使わないなら Moshi (+Kotshi) を選択肢に⼊入れましょう ▸ ※ 修正漏漏れで発表時は Kotshi と書いていましたが、Moshi です 30
Slide 31
Slide 31 text
Thanks おしまい ▸ Jumpei Matsuda @red_fat_daruma (jmatsu on GitHub) ▸ DeployGate で働きながら Alp でお⼿手伝い ▸ DroidKaigi 2020 スタッフ ▸ 公式アプリレビュワー ▸ 発表者 ▸ KotlinConf 2019、コペンハーゲン(のビールと飯)の話もしましょう 31