kotlinx.serialization: มันคืออะไร คำอธิบายประกอบและการซีเรียลไลซ์เป็น JSON

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-03-15 เวลาอ่าน: 12 นาที

kotlinx.serialization เป็นไลบรารีแบบหลายแพลตฟอร์มจาก JetBrains สำหรับแปลง Kotlin-ออบเจกต์เป็น JSON, ProtoBuf, CBOR และรูปแบบอื่น ๆ โดยไม่ใช้รีเฟลกชัน แตกต่างจาก Gson และ Moshi ตรงที่มันสร้างโค้ดซีเรียลไลเซอร์ในขั้นตอนคอมไพล์ผ่านคำอธิบายประกอบ @Serializable ซึ่งให้ประสิทธิภาพสูงและความปลอดภัยของชนิดข้อมูล ตามข้อมูลจาก GitHub Kotlin/kotlinx.serialization ไลบรารีรองรับ Kotlin/JVM, Kotlin/Native, Kotlin/JS และ Kotlin/Wasm.

หัวข้อสำคัญ

  • kotlinx.serialization — การซีเรียลไลซ์แบบ compile-time: โค้ดถูกสร้างขึ้นในขั้นตอนคอมไพล์ ไม่ใช้รีเฟลกชัน
  • @Serializable — คำอธิบายประกอบหลักที่เริ่มต้นการสร้างซีเรียลไลเซอร์สำหรับคลาส
  • Json {} builder — การกำหนดค่า JSON ผ่าน Json { ignoreUnknownKeys = true; prettyPrint = true }
  • ความหลายแพลตฟอร์ม — ไลบรารีทำงานบน JVM, Native, JS และ Wasm โดยไม่เปลี่ยน API
  • ซีเรียลไลเซอร์แบบกำหนดเอง — ผ่านอินเทอร์เฟซ KSerializer สำหรับรูปแบบข้อมูลที่ไม่ได้มาตรฐาน

kotlinx.serialization คืออะไร

kotlinx.serialization คือไลบรารีการซีเรียลไลซ์ในตัวสำหรับ Kotlin ที่พัฒนาโดย JetBrains ซึ่งเป็นส่วนหนึ่งของระบบนิเวศ Kotlin อย่างเป็นทางการ ข้อแตกต่างหลักจากโซลูชันอื่น (Gson, Moshi, Jackson) คือมันไม่ใช้รีเฟลกชันในระหว่างการทำงาน แทนที่จะเป็นอย่างนั้นโค้ดซีเรียลไลเซอร์จะถูกสร้างขึ้นในขั้นตอนคอมไพล์โดยใช้ Kotlin Symbol Processing (KSP) หรือ Kotlin Compiler Plugin ซึ่งทำให้ประสิทธิภาพดีขึ้นถึง 3-5 เท่าเมื่อเทียบกับ Gson และรับประกันความปลอดภัยของชนิดข้อมูล

ไลบรารีรองรับสี่รูปแบบอย่างเป็นทางการ: JSON (ผ่านโมดูล kotlinx-serialization-json), ProtoBuf (kotlinx-serialization-protobuf), CBOR (kotlinx-serialization-cbor) และ HOCON (kotlinx-serialization-hocon) แต่ละรูปแบบถูกเพิ่มเป็น dependencies แยกต่างหากใน build.gradle.kts ซึ่งช่วยให้ไม่ต้องดึงไลบรารีที่ไม่จำเป็นเข้ามาในโปรเจกต์ สำหรับแต่ละรูปแบบจะมีชุดพารามิเตอร์การกำหนดค่าของตัวเอง

ความหลายแพลตฟอร์ม เป็นฟีเจอร์สำคัญของไลบรารี คลาสเดียวกันที่มี @Serializable ทำงานบนเป้าหมายทั้งหมด: JVM (Android, Backend), Native (iOS), JS (Web, React) และ Wasm (WebAssembly) นักพัฒนาไม่จำเป็นต้องเขียนการใช้งานการซีเรียลไลซ์ที่แตกต่างกันสำหรับแต่ละแพลตฟอร์ม — โค้ดยังคงเป็นเอกภาพ ซึ่งมีคุณค่าอย่างยิ่งในโปรเจกต์ Kotlin Multiplatform Mobile (KMM) ที่โค้ดร่วมถูกแบ่งระหว่าง Android และ iOS

การสร้างโค้ดแบบ compile-time ทำงานอย่างไร

การสร้างโค้ด ใน kotlinx.serialization เกิดขึ้นในสามขั้นตอน ในขั้นตอนแรกคอมไพเลอร์ Kotlin ตรวจพบคำอธิบายประกอบ @Serializable บนคลาสและส่งต่อไปยัง Kotlin Symbol Processing (KSP) พลักอิน ในขั้นตอนที่สอง KSP สร้างออบเจกต์ซีเรียลไลเซอร์ที่ใช้งานอินเทอร์เฟซ KSerializer ในขั้นตอนที่สามโค้ดที่สร้างขึ้นจะถูกคอมไพล์พร้อมกับโค้ดต้นฉบับของโปรเจกต์ ผลลัพธ์คือไม่มีขั้นตอนใดถูกดำเนินการในระหว่างการทำงานของแอปพลิเคชัน

ซีเรียลไลเซอร์ที่สร้างขึ้นจะทำงานโดยตรงกับฟิลด์ของคลาสผ่าน getters และ setters โดยไม่ใช้รีเฟลกชัน ซึ่งหมายความว่าฟิลด์ที่มีตัวปรับ private ก็จะถูกซีเรียลไลซ์หากมี @Serializable ประสิทธิภาพของวิธีการนี้ใกล้เคียงกับการซีเรียลไลซ์ด้วยมือ: สำหรับคลาสที่เรียบง่าย (5-10 ฟิลด์) เวลาการซีเรียลไลซ์ประมาณ 10-50 ไมโครวินาที สำหรับกราฟออบเจกต์ที่ซับซ้อน สูงถึง 200 ไมโครวินาทีต่อ 1,000 ออบเจกต์

สำหรับการเชื่อมต่อไลบรารีในโปรเจกต์ Android หรือ Kotlin/JVM ต้องเพิ่มพลักอินและ dependencies ใน build.gradle.kts พลักอิน org.jetbrains.kotlin.plugin.serialization เวอร์ชันที่ตรงกับเวอร์ชันของ Kotlin จะเปิดใช้งานการสร้างโค้ด ไลบรารี kotlinx-serialization-json ถูกเพิ่มในส่วน dependencies ด้วยเวอร์ชันที่ไม่ขึ้นอยู่กับเวอร์ชันของ Kotlin

kotlin
// build.gradle.kts — การเพิ่ม kotlinx.serialization
plugins {
    val kotlinVersion = "2.1.0"
    kotlin("jvm") version kotlinVersion
    kotlin("plugin.serialization") version kotlinVersion
}

dependencies {
    // โมดูลหลักสำหรับการซีเรียลไลซ์
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")

    // รูปแบบเพิ่มเติม
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf:1.7.3")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-cbor:1.7.3")
}

การใช้งานพื้นฐาน: การซีเรียลไลซ์เป็น JSON

JSON เป็นรูปแบบที่ได้รับความนิยมมากที่สุดใน kotlinx.serialization สำหรับการซีเรียลไลซ์ออบเจกต์ เพิ่มคำอธิบายประกอบ @Serializable ให้ data class แล้วเรียก Json.encodeToString() สำหรับการดีซีเรียลไลซ์ใช้ Json.decodeFromString() พร้อมระบุชนิด ไลบรารีจะจัดการฟิลด์ null, รายการ, ออบเจกต์ที่ซ้อนกันและ enums โดยอัตโนมัติ โดยค่าเริ่มต้นฟิลด์ทั้งหมดของคลาสจำเป็นต้องมี เว้นแต่จะระบุเป็นอื่น

การกำหนดค่า JSON ทำผ่าน Json {} builder ในคอนสตรักเตอร์สามารถส่ง ignoreUnknownKeys = true เพื่อข้ามฟิลด์ที่ไม่รู้จักในการดีซีเรียลไลซ์, prettyPrint = true สำหรับผลลัพธ์ที่จัดรูปแบบ, coerceInputValues = true สำหรับแปลงค่าที่ไม่ถูกต้องเป็นค่าเริ่มต้น นอกจากนี้ยังมีการตั้งค่า encodeDefaults (ซีเรียลไลซ์ฟิลด์ที่มีค่าเริ่มต้น) และ classDiscriminator (ชื่อฟิลด์สำหรับการซีเรียลไลซ์แบบพหุรูป)

kotlin
// ตัวอย่างการซีเรียลไลซ์และดีซีเรียลไลซ์ JSON
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration

@Serializable
data class Project(
    val name: String,
    val stars: Int,
    val isActive: Boolean = true,
    val languages: List<String> = emptyList()
)

fun main() {
    val project = Project(
        name = "kotlinx.serialization",
        stars = 7200,
        languages = listOf("Kotlin", "Java")
    )

    // การซีเรียลไลซ์เป็น JSON ด้วย prettyPrint
    val json = Json { prettyPrint = true }
    val jsonString = json.encodeToString(project)
    println(jsonString)
    /*
    {
        "name": "kotlinx.serialization",
        "stars": 7200,
        "isActive": true,
        "languages": ["Kotlin", "Java"]
    }
    */

    // การดีซีเรียลไลซ์จาก JSON
    val decoded = json.decodeFromString<Project>(jsonString)
    println(decoded.name)  // kotlinx.serialization
}

ตัวอย่างแสดงถึง วงจรพื้นฐาน ของการซีเรียลไลซ์และดีซีเรียลไลซ์ Data class Project ที่มี @Serializable จะได้รับ encodeToString และ decodeFromString โดยอัตโนมัติ ฟิลด์ isActive มีค่าเริ่มต้นเป็น true — หากไม่มีฟิลด์นี้ใน JSON จะใช้ค่าเริ่มต้น หากมีฟิลด์ที่ไม่รู้จักใน JSON โดยไม่มี ignoreUnknownKeys = true จะเกิดข้อยกเว้น SerializationException

การซีเรียลไลซ์แบบพหุรูปของ sealed class

Sealed class เป็นหนึ่งในกรณีการใช้งานที่มีพลังมากที่สุดของ kotlinx.serialization ไลบรารีรองรับการซีเรียลไลซ์แบบพหุรูปสำหรับลำดับชั้น sealed class โดยไม่ต้องตั้งค่าเพิ่มเติม: เพียงระบุ sealed class และคลาสสืบทอดทั้งหมดด้วย @Serializable เมื่อซีเรียลไลซ์จะเพิ่มฟิลด์ “type” (กำหนดค่าได้ผ่าน classDiscriminator) ซึ่งใช้ในการระบุชนิดเฉพาะเมื่อดีซีเรียลไลซ์

kotlin
// การซีเรียลไลซ์แบบพหุรูปของ sealed class
@Serializable
sealed class Response

@Serializable
data class Success(val data: String) : Response()

@Serializable
data class Error(val code: Int, val message: String) : Response()

fun main() {
    val json = Json { classDiscriminator = "result_type" }

    val responses: List<Response> = listOf(
        Success(data = "Data loaded"),
        Error(code = 404, message = "Not found")
    )

    val jsonString = json.encodeToString(responses)
    println(jsonString)
    /*
    [
        {"result_type":"Success","data":"Data loaded"},
        {"result_type":"Error","code":404,"message":"Not found"}
    ]
    */

    val decoded = json.decodeFromString<List<Response>>(jsonString)
    when (val first = decoded[0]) {
        is Success -> println("Success: ${first.data}")
        is Error -> println("Error: ${first.code}")
    }
}

การซีเรียลไลซ์แบบพหุรูปของ sealed class มีประโยชน์อย่างยิ่งใน ไคลเอนต์ API ที่เซิร์ฟเวอร์ส่งคืนประเภทคำตอบที่แตกต่างกัน หากไม่มี kotlinx.serialization จะต้องเขียนดีซีเรียลไลเซอร์ด้วยตนเองด้วย when ตามฟิลด์ตัวแบ่งชนิด ด้วยไลบรารีทำได้ด้วยคำอธิบายประกอบเดียว classDiscriminator ช่วยให้เปลี่ยนชื่อฟิลด์มาร์กเกอร์ (ค่าเริ่มต้น “type”) เป็นค่าใดก็ได้ที่เซิร์ฟเวอร์คาดหวัง

คำอธิบายประกอบ kotlinx.serialization: ภาพรวมที่สมบูรณ์

ไลบรารี มีชุดคำอธิบายประกอบสำหรับปรับแต่งการซีเรียลไลซ์อย่างละเอียด หลักคือ @Serializable สำหรับคลาส เพิ่มเติม: @SerialName สำหรับกำหนดชื่อฟิลด์ใน JSON (หากแตกต่างจากชื่อ Kotlin), @Transient สำหรับแยกฟิลด์ออกจากการซีเรียลไลซ์, @Required สำหรับฟิลด์ที่ต้องมีอยู่ใน JSON, @EncodeDefault สำหรับบังคับซีเรียลไลซ์ฟิลด์ที่มีค่าเริ่มต้น

คำอธิบายประกอบวัตถุประสงค์ตัวอย่าง
@Serializableเปิดใช้งานการสร้างซีเรียลไลเซอร์สำหรับคลาส@Serializable data class User
@SerialNameกำหนดชื่อฟิลด์อื่นในรูปแบบ@SerialName("user_name") val name: String
@Transientแยกฟิลด์ออกจากการซีเรียลไลซ์@Transient val cache: MutableMap
@Requiredฟิลด์จำเป็นต้องมีใน JSON เมื่อดีซีเรียลไลซ์@Required val id: String
@EncodeDefaultซีเรียลไลซ์ฟิลด์แม้มีค่าเริ่มต้น@EncodeDefault val type: Type = Type.A
@Serializerผูกซีเรียลไลเซอร์แบบกำหนดเองกับคลาส@Serializer(forClass = Date::class)

คำอธิบายประกอบ @SerialName สำคัญเมื่อทำงานกับ API ที่ชื่อฟิลด์เป็น snake_case แต่สไตล์ Kotlin เป็น camelCase เช่น เซิร์ฟเวอร์ส่ง “user_id” แต่ในโค้ด Kotlin ใช้ userId @SerialName(“user_id”) แก้ปัญหานี้โดยไม่ต้องมีแมปเปอร์เพิ่มเติม @Transient สะดวกสำหรับฟิลด์ที่ไม่ต้องส่งไปเซิร์ฟเวอร์ — เช่น ค่าที่คำนวณชั่วคราวหรือแคช

@Required เป็นทางเลือกสำหรับฟิลด์แบบ nullable

โดยค่าเริ่มต้น ฟิลด์ทั้งหมดใน kotlinx.serialization จำเป็นต้องมี หากฟิลด์อาจไม่มีในJSON ต้องทำให้เป็น nullable (String?) หรือกำหนดค่าเริ่มต้น (val name: String = “”) อย่างไรก็ตาม อาจมีสถานการณ์ที่ฟิลด์ไม่ใช่ nullable ใน Kotlin แต่อาจไม่มีใน JSON เนื่องจากการกำหนดเวอร์ชัน API ในกรณีนี้ @Required จะโยน SerializationException เมื่อไม่มีฟิลด์ ในขณะที่ค่าเริ่มต้นจะเติม default โดยไม่มีข้อผิดพลาด

ซีเรียลไลเซอร์แบบกำหนดเอง: KSerializer และการจัดการด้วยตนเอง

KSerializer คืออินเทอร์เฟซที่ซีเรียลไลเซอร์ทั้งหมดใน kotlinx.serialization ต้องใช้งาน หากการสร้างโค้ดมาตรฐานไม่เหมาะสม (เช่น สำหรับ Date, Bitmap หรือรูปแบบไบนารีเฉพาะ) สามารถเขียนซีเรียลไลเซอร์ของตัวเองได้ โดยต้องใช้งานเมธอด serialize() และ deserialize() พร้อมทั้งให้ descriptor — คำอธิบายโครงสร้างสำหรับ schema ของรูปแบบ

ซีรียาลไซเซอร์แบบกำหนดเองเชื่อมต่อได้สองวิธี: ผ่านคำอธิบายประกอบ @Serializable(with = MySerializer::class) สำหรับการผูกกับคลาสโดยเฉพาะ หรือทั่วไปผ่าน Json { serializersModule = ... } สำหรับการผูกกับทุกอินสแตนซ์ของชนิด วิธีที่สองเป็นที่นิยมกว่าสำหรับชนิดที่ติดตั้งอยู่ในตัว (Date, UUID) เพื่อไม่ต้องเขียนคำอธิบายประกอบใส่ทุกฟิลด์

kotlin
// ซีเรียลไลเซอร์แบบกำหนดเองสำหรับ java.util.Date
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

object DateSerializer : KSerializer<Date> {
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)

    override val descriptor: SerialDescriptor =
        PrimitiveSerialDescriptor("Date", PrimitiveKind.STRING)

    override fun serialize(encoder: Encoder, value: Date) {
        encoder.encodeString(dateFormat.format(value))
    }

    override fun deserialize(decoder: Decoder): Date {
        return dateFormat.parse(decoder.decodeString())
    }
}

// การใช้งานซีเรียลไลเซอร์แบบกำหนดเอง
@Serializable
data class Event(
    val title: String,
    @Serializable(with = DateSerializer::class)
    val date: Date
)

fun main() {
    val json = Json { prettyPrint = true }
    val event = Event("Release", Date())
    println(json.encodeToString(event))
}

ในตัวอย่าง DateSerializer แปลง java.util.Date เป็นสตริง ISO 8601 หากไม่มีซีเรียลไลเซอร์แบบกำหนดเอง kotlinx.serialization ไม่สามารถทำงานกับ Date ได้ — นี่เป็นชนิดที่ไม่อยู่ในไลบรารีมาตรฐานของ Kotlin @Serializable(with = DateSerializer::class) บนฟิลด์เฉพาะจะเชื่อมต่อซีเรียลไลเซอร์เฉพาะกับฟิลด์นี้ สำหรับการลงทะเบียน Date ทั้งหมดในระดับโลก ใช้ Json { serializersModule = SerializersModule { contextual(DateSerializer) } }

รูปแบบการซีเรียลไลซ์: JSON, ProtoBuf, CBOR, HOCON

kotlinx.serialization ไม่ได้จำกัดเฉพาะ JSON ไลบรารีรองรับสี่รูปแบบในตัว แต่ละรูปแบบมีโมดูลและการกำหนดค่าของตัวเอง JSON (kotlinx-serialization-json) — อเนกประสงค์ อ่านได้โดยมนุษย์ เหมาะสำหรับ REST API ProtoBuf (kotlinx-serialization-protobuf) — ไบนารี กะทัดรัด มี schema ที่จำเป็น สำหรับไมโครเซอร์วิสที่มีโหลดสูง CBOR (kotlinx-serialization-cbor) — ไบนารีที่เทียบเท่า JSON สะดวกสำหรับ IoT และอุปกรณ์มือถือที่มีข้อจำกัดด้านปริมาณข้อมูล HOCON (kotlinx-serialization-hocon) — รูปแบบการกำหนดค่าที่เข้ากันได้กับ TypeSafe Config

รูปแบบโมดูลประเภทSchemaการใช้งานทั่วไป
JSONkotlinx-serialization-jsonข้อความไม่บังคับREST API, การจัดเก็บข้อมูล
ProtoBufkotlinx-serialization-protobufไบนารีจำเป็น (.proto)ไมโครเซอร์วิส, gRPC
CBORkotlinx-serialization-cborไบนารีไม่บังคับIoT, อุปกรณ์มือถือ
HOCONkotlinx-serialization-hoconข้อความไม่บังคับไฟล์การกำหนดค่า

ProtoBuf ต้องการการกำหนด schema ในไฟล์ .proto แต่ kotlinx-serialization-protobuf สร้างคลาส Kotlin โดยตรงจาก @Serializable โดยไม่ต้องใช้ .proto ซึ่งช่วยให้การพัฒนาง่ายขึ้น: เพิ่มคำอธิบายประกอบ data class และใช้ ProtoBuf.encodeToByteArray() CBOR มีความสำคัญโดยเฉพาะสำหรับ Android เมื่อต้องการส่งข้อมูลไบนารีขนาดกะทัดรัดผ่าน NFC หรือ BLE ขนาดข้อความ CBOR โดยเฉลี่ยเล็กกว่า JSON 20-30% สำหรับชุดข้อมูลเดียวกัน

การเลือกรูปแบบสำหรับโปรเจกต์

สำหรับ REST API ในแอปพลิเคชันมือถือ JSON เหมาะที่สุด — สามารถดีบักได้โดยไม่ต้องใช้เครื่องมือเพิ่มเติม อ่านได้ในล็อกและเข้ากันได้กับแบ็กเอนด์ทุกประเภท หากแอปพลิเคชันส่งข้อมูลปริมาณมากระหว่างไมโครเซอร์วิส (หลายร้อยเมกะไบต์) — ProtoBuf จะให้ความเร็วที่ดีขึ้นถึง 5 เท่าด้วยการเข้ารหัสแบบไบนารี สำหรับการจัดเก็บการตั้งค่าในไฟล์ ใช้ HOCON หรือ JSON สำหรับอุปกรณ์ที่มีข้อจำกัดด้านปริมาณข้อมูลอย่างเข้มงวด (เซ็นเซอร์ IoT) — CBOR

ข้อผิดพลาดทั่วไปในการทำงานกับ kotlinx.serialization

ข้อผิดพลาดแรก — การละเลย unknown keys เมื่อดีซีเรียลไลซ์ หากเซิร์ฟเวอร์เพิ่มฟิลด์ใหม่ แต่คุณมี ignoreUnknownKeys = false แอปพลิเคชันจะล้มด้วย SerializationException โดยค่าเริ่มต้นแฟล็กนี้ถูกปิด วิธีแก้: ตั้งค่า Json { ignoreUnknownKeys = true } สำหรับโค้ด production เพื่อความทนทานต่อการเปลี่ยนแปลง API

ข้อผิดพลาดที่สอง — การซีเรียลไลซ์ฟิลด์ internal หรือ private ใน data class ใน Kotlin data class ฟิลด์ทั้งหมดใน primary constructor จะถูกซีเรียลไลซ์โดยค่าเริ่มต้น หากฟิลด์มีข้อมูลที่ละเอียดอ่อน (รหัสผ่าน, โทเค็น) ต้องระบุ @Transient หรือย้ายออกจาก primary constructor @Transient แยกฟิลด์ออกจาก JSON โดยสมบูรณ์ แต่ใน constructor อาจทำให้เกิดข้อผิดพลาด — ควรกำหนดฟิลด์ดังกล่าวในเนื้อหาของคลาสด้วย @Transient

ข้อผิดพลาดที่สาม — การซีเรียลไลซ์แบบพหุรูปโดยไม่มี sealed class หากใช้ open class แทน sealed kotlinx.serialization ต้องการการลงทะเบียนคลาสสืบทอดทั้งหมดอย่างชัดเจนใน serializersModule แตกต่างจาก sealed class ที่คอมไพเลอร์รู้จักคลาสสืบทอดทั้งหมด open class อนุญาตให้ขยายได้ตามอำเภอใจ — ไลบรารีไม่สามารถระบุชนิดย่อยทั้งหมดได้โดยอัตโนมัติ การลงทะเบียนทำผ่าน Json { serializersModule = SerializersModule { polymorphic(Base::class) { subclass(Derived::class) } } }

ข้อผิดพลาดด้านเวอร์ชันของไลบรารี

เวอร์ชันของ kotlinx.serialization ต้องเข้ากันได้กับเวอร์ชันของ Kotlin JetBrains เผยแพร่ตารางความเข้ากันได้: kotlinx-serialization 1.6.x เข้ากันได้กับ Kotlin 1.9.x, 1.7.x — กับ Kotlin 2.0.x และ 2.1.x เวอร์ชันที่ไม่ตรงกันทำให้เกิดข้อผิดพลาดการคอมไพล์ที่คลุมเครือ “Symbol 'serializer' is missing” ตรวจสอบเวอร์ชันล่าสุดบน mavenCentral หรือในที่เก็บ GitHub ของโปรเจกต์เสมอ

คำถามที่พบบ่อย

kotlinx.serialization แตกต่างจาก Gson และ Moshi อย่างไร?

kotlinx.serialization ใช้การสร้างโค้ดแบบ compile-time ผ่าน KSP ในขณะที่ Gson และ Moshi ใช้รีเฟลกชันใน runtime ซึ่งให้ข้อได้เปรียบด้านประสิทธิภาพ (เร็วกว่า Gson 3-5 เท่า) และความปลอดภัยของชนิดข้อมูล Gson ซีเรียลไลซ์ฟิลด์ใดก็ได้โดยไม่ต้องมีคำอธิบายประกอบ ซึ่งอาจนำไปสู่การรั่วไหลของข้อมูล kotlinx.serialization ต้องการคำอธิบายประกอบ @Serializable อย่างชัดเจน ซึ่งปลอดภัยกว่า Moshi รองรับ codegen เช่นกัน แต่เฉพาะ JVM และ Android

kotlinx.serialization รองรับ Kotlin Multiplatform หรือไม่?

ใช่, kotlinx.serialization เป็นไลบรารีแบบหลายแพลตฟอร์มอย่างเป็นทางการของ JetBrains มันทำงานบน Kotlin/JVM (Android, Backend), Kotlin/Native (iOS), Kotlin/JS (Web, React) และ Kotlin/Wasm API เป็นเอกภาพสำหรับทุกแพลตฟอร์ม: @Serializable + Json.encodeToString() ทำงานเหมือนกันทุกที่ สำหรับ iOS ไม่ต้องการการตั้งค่าเพิ่มเติม — Kotlin/Native คอมไพล์โค้ดที่ซีเรียลไลซ์เป็นไบนารีเนทีฟ

จัดการกับฟิลด์ null ใน JSON อย่างไร?

ฟิลด์แบบ Nullable (String?) จะถูกดีซีเรียลไลซ์เป็น null หากไม่มีค่าหรือระบุ null ใน JSON สำหรับฟิลด์ non-nullable (String) ที่ไม่มีค่าเริ่มต้น การไม่มีฟิลด์ใน JSON จะทำให้เกิด SerializationException หากคุณต้องการให้ค่า null ไม่ปรากฏใน JSON ให้ตั้งค่า Json { encodeDefaults = false } ซึ่งจะแยกฟิลด์ทั้งหมดที่มีค่า default (รวมถึง null สำหรับ nullable) ออกจากผลลัพธ์

จะทำอย่างไรหากเซิร์ฟเวอร์ส่งฟิลด์แบบ snake_case?

ใช้ @SerialName(“snake_case_name”) บนแต่ละฟิลด์ที่ชื่อแตกต่างจากรูปแบบ Kotlin หรืออีกทางเลือกหนึ่ง สำหรับ Kotlin 2.0+ มี Json { namingStrategy = JsonNamingStrategy.SnakeCase } — การแปลง camelCase ↔ snake_case โดยอัตโนมัติ การตั้งค่านี้ใช้กับทุกฟิลด์พร้อมกัน หากต้องการปรับแต่งบางส่วน ให้รวม @SerialName เข้ากับกลยุทธ์ระดับโลก

สามารถซีรียาลไซ Kotlin Flow หรือ coroutine ได้หรือไม่?

ไม่, Flow และโครูทีนไม่สามารถซีเรียลไลซ์ได้โดยตรง — มันแสดงถึงการทำงานแบบอะซิงโครนัส ไม่ใช่ข้อมูล สำหรับการส่งข้อมูลจาก Flow ต้องรวบรวมเป็นคอลเล็กชันผ่าน .toList() ในโครูทีนแล้วซีเรียลไลซ์คอลเล็กชัน ในทำนองเดียวกัน ไม่สามารถซีเรียลไลซ์ Job, Deferred หรือ Continuation ได้ ซีเรียลไลซ์เฉพาะ data class — โมเดลข้อมูลที่ไม่มีตรรกะเชิงพฤติกรรม

สรุป

  • kotlinx.serialization — การซีเรียลไลซ์แบบ compile-time ผ่าน @Serializable โดยไม่ใช้รีเฟลกชัน มีประสิทธิภาพสูงกว่า Gson ถึง 5 เท่า
  • @Serializable, @SerialName, @Transient — คำอธิบายประกอบหลักสำหรับปรับแต่งการซีเรียลไลซ์ฟิลด์และคลาส
  • Json {} builder กำหนดค่า JSON: ignoreUnknownKeys, prettyPrint, coerceInputValues, encodeDefaults
  • Sealed class และการซีเรียลไลซ์แบบพหุรูป — รองรับลำดับชั้นชนิดได้อย่างราบรื่นโดยไม่ต้องใช้โค้ดเพิ่มเติม
  • KSerializer — อินเทอร์เฟซสำหรับซีเรียลไลเซอร์แบบกำหนดเองสำหรับชนิดที่ไม่ได้มาตรฐาน (Date, Bitmap, UUID)
  • สี่รูปแบบ: JSON, ProtoBuf, CBOR, HOCON — เชื่อมต่อผ่านโมดูล API เป็นเอกภาพสำหรับทั้งหมด
  • ความหลายแพลตฟอร์ม — โค้ดเดียวสำหรับ JVM, Native, JS และ Wasm; สำคัญสำหรับ KMM และโมดูลร่วม

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม