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