การดีซีเรียลไลเซชัน: คืออะไร กระบวนการกู้คืนข้อมูล

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

การดีซีเรียลไลเซชันคือกระบวนการกู้คืนออบเจกต์จากสตรีมข้อมูล JSON, XML หรือ Protobuf ซึ่งจำเป็นสำหรับแอปพลิเคชันมือถือที่ทำงานกับ API ระยะไกล ตามข้อมูลจาก Apple Developer (2026) การจัดการข้อมูลขาเข้าที่ไม่ถูกต้องยังคงเป็นสาเหตุทั่วไปของความล้มเหลวบนอุปกรณ์ JSONDecoder บน iOS และ Gson บน Android เป็นเครื่องมือมาตรฐาน แต่แต่ละอย่างมีคุณสมบัติและข้อจำกัดของตัวเอง

ประเด็นสำคัญ

  • การดีซีเรียลไลเซชัน คือการกู้คืนออบเจกต์ที่ระบุชนิดจาก JSON, XML หรือ Protobuf เพื่อใช้ในโค้ด
  • Codable คือโปรโตคอลของ Apple สำหรับการดีซีเรียลไลเซชันอัตโนมัติใน Swift ที่รองรับการสร้างโค้ด
  • Moshi คือไลบรารี Android จาก Square พร้อมตัวเลือก codegen และ reflection สำหรับสถานการณ์ต่างๆ
  • Type mismatch คือข้อผิดพลาดที่พบบ่อยที่สุดเมื่อชนิดฟิลด์ JSON และคุณสมบัติของโมเดลไม่ตรงกัน
  • kotlinx.serialization คือโซลูชันอย่างเป็นทางการของ JetBrains พร้อมการสร้างโค้ดที่ปลอดภัยโดยคอมไพเลอร์

การดีซีเรียลไลเซชันคืออะไร?

การดีซีเรียลไลเซชัน คือกระบวนการแปลงสตรีมไบต์หรือข้อความที่มีโครงสร้างเป็นออบเจกต์ของภาษาโปรแกรม ในการพัฒนามือถือ กระบวนการนี้เกิดขึ้นทุกครั้งที่แอปพลิเคชันได้รับการตอบสนองจากเซิร์ฟเวอร์: สตริง JSON จะกลายเป็นอินสแตนซ์ของคลาส User, Order หรือ Product ความเสถียรของหน้าจอที่แสดงข้อมูลให้ผู้ใช้ขึ้นอยู่กับความถูกต้องของการดีซีเรียลไลเซชันโดยตรง

ความแตกต่างจากการซีเรียลไลเซชัน

การซีเรียลไลเซชันและการดีซีเรียลไลเซชันเป็นกระบวนการที่กลับกัน ซึ่งแทบจะไม่สมมาตรในทางปฏิบัติ การซีเรียลไลเซชัน แปลงออบเจกต์เป็นสตริงเพื่อส่งไปยังเซิร์ฟเวอร์ ในขณะที่การดีซีเรียลไลเซชันกู้คืนออบเจกต์จากสตริงที่ได้รับ เซิร์ฟเวอร์อาจส่งฟิลด์ที่ไม่มีอยู่ในโมเดลของไคลเอ็นต์ ใช้รูปแบบวันที่แตกต่าง หรือคืนค่า null แทนตัวเลข ตามข้อมูลจาก Square Engineering (2025) ความไม่สมมาตรของรูปแบบทำให้เกิดข้อผิดพลาดชั้นเครือข่าย 23% ในแอปพลิเคชัน Android เพื่อลดความเสี่ยง จะใช้การกำหนดเวอร์ชันสคีมาและข้อกำหนดสัญญาที่เข้มงวดผ่าน OpenAPI

รูปแบบข้อมูลสำหรับการดีซีเรียลไลเซชัน

JSON ยังคงเป็นรูปแบบที่ได้รับความนิยมมากที่สุดสำหรับ API บนมือถือ เนื่องจากการอ่านได้ของมนุษย์และการรองรับในตัว Protobuf จาก Google ใช้ในระบบที่มีโหลดสูง — มีขนาดกะทัดรัดกว่า JSON 3-6 เท่าและแยกวิเคราะห์ได้เร็วกว่า แต่ต้องสร้างโค้ดจากไฟล์ .proto และไม่สามารถอ่านได้หากไม่มีเครื่องมือ XML พบได้น้อยกว่าในแอปพลิเคชันมือถือสมัยใหม่ แต่ใช้ในบริการ SOAP ของระบบองค์กรและไฟล์กำหนดค่า Android MessagePack เป็นรูปแบบไบนารีที่มีโครงสร้างคล้ายกับ JSON แต่กะทัดรัดกว่า เป็นที่นิยมในระบบเรียลไทม์

การดีซีเรียลไลเซชันทำงานอย่างไร

กระบวนการดีซีเรียลไลเซชันผ่านสามขั้นตอน ขั้นแรก การทำโทเค็น แบ่งข้อความดิบเป็นโทเค็น: คีย์ สตริง ตัวเลข และตัวคั่น จากนั้น การวิเคราะห์วากยสัมพันธ์ ตรวจสอบความถูกต้องของโครงสร้าง — วงเล็บปิดหรือไม่ ชนิดของเครื่องหมายคำพูดถูกต้องหรือไม่ รูปแบบเป็นไปตาม RFC 8259 หรือไม่ ขั้นตอนสุดท้ายคือ การแมป ไปยังโมเดลออบเจกต์ของแอปพลิเคชัน ซึ่งแต่ละคีย์ JSON จะถูกกำหนดคุณสมบัติของคลาสโดยพิจารณากลยุทธ์การตั้งชื่อ

Reflection vs Code generation

มีสองแนวทางการแมปที่เกิดขึ้นในการพัฒนามือถือ Reflection (Gson, JSONSerialization) วิเคราะห์โครงสร้างคลาสในขณะรันไทม์ผ่าน Java Reflection API หรือ Objective-C runtime — ยืดหยุ่นและไม่ต้องการการกำหนดค่าเพิ่มเติม แต่ช้ากว่าและใช้หน่วยความจำมากกว่า Code generation (Moshi codegen, kotlinx.serialization, Codable) สร้างโค้ดในเวลาคอมไพล์: เร็วกว่า ปลอดภัยกว่าตามชนิด และไม่เปิดเผยโครงสร้างภายในผ่าน reflection JetBrains และ Square แนะนำการสร้างโค้ดสำหรับบิลด์ที่ใช้งานจริง — ประสิทธิภาพเพิ่มขึ้น 2-4 เท่าในการวัดประสิทธิภาพของ Google

swift
struct User: Codable {
    let id: Int
    let name: String
    let email: String
    let createdAt: Date
}

let json = """
{
    "id": 42,
    "name": "Alice",
    "email": "alice@example.com",
    "created_at": "2026-06-01T12:00:00Z"
}
"""
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let user = try decoder.decode(User.self, from: data)

ตัวอย่างการดีซีเรียลไลซ์ JSON เป็นโมเดล User ใน Swift กลยุทธ์ convertFromSnakeCase จะแปลงคีย์ API แบบ snake_case เป็นคุณสมบัติโมเดลแบบ camelCase โดยอัตโนมัติ — เป็นแนวปฏิบัติมาตรฐานในโปรเจกต์ iOS พารามิเตอร์ data คือไบต์ดิบของการตอบสนองจากเซิร์ฟเวอร์ที่ได้รับผ่าน URLSession การจัดการข้อผิดพลาดผ่าน try ช่วยให้ตรวจจับ JSON ที่ไม่ถูกต้องได้โดยไม่ทำให้แอปพลิเคชันล้มเหลว

บทบาทของกลยุทธ์การถอดรหัส

JSONDecoder รองรับสี่กลยุทธ์คีย์: useDefaultKeys (การจับคู่ที่แน่นอน), convertFromSnakeCase (snake_case → camelCase), custom (closure) และ convertFromKebabCase (kebab-case → camelCase) สำหรับวันที่ มี .iso8601, .secondsSince1970, .millisecondsSince1970 และ dateFormatter แบบกำหนดเอง การเลือกกลยุทธ์ที่ถูกต้องเป็นขั้นตอนแรกสู่การดีซีเรียลไลเซชันที่แข็งแกร่ง ซึ่งป้องกันข้อผิดพลาดรูปแบบไม่ตรงกันส่วนใหญ่

การดีซีเรียลไลเซชันบน iOS

JSONDecoder คือกลไกมาตรฐานการดีซีเรียลไลเซชันใน iOS SDK ที่ทำงานกับโปรโตคอล Codable JSONDecoder จะแยกวิเคราะห์ JSON เป็นอินสแตนซ์ของ struct หรือ class โดยอัตโนมัติ รองรับออบเจกต์ที่ซ้อนกัน อาร์เรย์ และชนิดพื้นฐาน สำหรับตรรกะแบบกำหนดเอง จะใช้เมธอด init(from: Decoder) — ซึ่งช่วยให้จัดการรูปแบบที่ไม่เป็นมาตรฐาน ฟิลด์ที่หายไปในเวอร์ชัน API เก่า หรือรวมหลายคีย์ JSON เป็นคุณสมบัติเดียว

swift
struct Order: Decodable {
    let orderId: String
    let amount: Double
    let status: OrderStatus

    enum OrderStatus: String, Decodable {
        case pending, confirmed, shipped, cancelled
    }
}

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let order = try decoder.decode(Order.self, from: jsonData)

DateDecodingStrategy กำหนดว่า JSONDecoder ตีความสตริงวันที่อย่างไร .iso8601 ถูกใช้บ่อยที่สุด — รูปแบบมาตรฐานของ REST API Enum OrderStatus ที่ซ้อนกันจะถูกถอดรหัสโดยอัตโนมัติจากค่าสตริง JSON ซึ่งช่วยหลีกเลี่ยงตัวเลขวิเศษและทำให้โค้ดอธิบายตนเองได้ — สถานะคำสั่งซื้อจะมีชุดค่าที่กำหนดไว้อย่างเคร่งครัดเสมอ

Property Wrappers ใน Codable

ตั้งแต่ Swift 4.2 Codable รองรับ property wrappers สำหรับการดีซีเรียลไลเซชันแบบกำหนดเองของคุณสมบัติแต่ละรายการ @DefaultValue เป็น wrapper ยอดนิยมที่ตั้งค่าเริ่มต้นหากฟิลด์หายไปใน JSON @LosslessString แปลงสตริงเป็นตัวเลขและในทางกลับกัน ซึ่งมีประโยชน์อย่างยิ่งเมื่อเซิร์ฟเวอร์ส่ง id เป็นสตริง "123" แต่โมเดลคาดหวัง Int Property wrappers ลดโค้ดเทมเพลตใน init(from:) และทำให้โมเดลสะอาดขึ้น

การดีซีเรียลไลเซชันบน Android

บน Android การเลือกไลบรารีดีซีเรียลไลเซชันขึ้นอยู่กับภาษาและข้อกำหนดของโปรเจกต์ Gson จาก Google เป็นตัวเลือกที่พบบ่อยที่สุด ทำงานผ่าน reflection แต่มีปัญหาด้านประสิทธิภาพกับลำดับชั้นที่ซับซ้อน Moshi จาก Square รองรับทั้ง reflection และ code generation ใช้หน่วยความจำน้อยกว่าและประมวลผลการตอบสนองขนาดใหญ่ได้เร็วกว่า kotlinx.serialization จาก JetBrains เป็นโซลูชัน Kotlin ดั้งเดิมที่ผสานรวมกับคอมไพเลอร์และไม่ใช้ reflection เลย

kotlin
@Serializable
data class User(
    @SerialName("user_id")
    val userId: Int,
    val name: String,
    val email: String,
    @SerialName("created_at")
    val createdAt: String
)

val json = Json { ignoreUnknownKeys = true }
val user = json.decodeFromString<User>(response)

@Serializable คือคำอธิบายประกอบของคอมไพเลอร์ Kotlin ที่เปิดใช้งานการสร้างโค้ดสำหรับคลาส พารามิเตอร์ ignoreUnknownKeys ป้องกันความล้มเหลวหากเซิร์ฟเวอร์ส่งฟิลด์ที่ไม่มีในโมเดล สำหรับการแมปคีย์ snake_case จะใช้ @SerialName — ซึ่งเทียบเท่ากับ convertFromSnakeCase จาก iOS ตามข้อมูลจาก JetBrains (2026) ไลบรารีรองรับหลายแพลตฟอร์ม: คลาส Serializable เดียวกันทำงานบน Android, iOS (KMP) และ Kotlin ฝั่งเซิร์ฟเวอร์

การเปรียบเทียบ Gson, Moshi และ kotlinx.serialization

การเลือกระหว่างไลบรารีเป็นการแลกเปลี่ยนระหว่างความเร็วและความยืดหยุ่น Gson เหมาะสำหรับต้นแบบและโปรเจกต์ Java — ไม่ต้องการคำอธิบายประกอบและทำงานได้ทันที Moshi อยู่ในตำแหน่งกลาง: codegen ผ่าน @JsonClass(generateAdapter = true) ให้ความเร็วใกล้เคียงกับ kotlinx.serialization ในขณะที่โหมด reflection ให้ความยืดหยุ่นของ Gson kotlinx.serialization เป็นตัวเลือกที่เร็วที่สุดสำหรับโปรเจกต์ Kotlin บริสุทธิ์ แต่ต้องใช้ Kotlin 1.4+ และปลั๊กอิน Kotlin Serialization ใน Gradle

ไลบรารีกลไกความเร็วKMP
GsonReflectionต่ำไม่
MoshiReflection / Codegenปานกลาง / สูงไม่
kotlinx.serializationCodegen ของคอมไพเลอร์สูงใช่

ข้อผิดพลาดทั่วไปและการป้องกัน

Type mismatch คือสถานการณ์ที่ JSON มีค่าของชนิดหนึ่ง แต่โมเดลคาดหวังอีกชนิดหนึ่ง เซิร์ฟเวอร์ส่งสตริง "42" แทนตัวเลข หรือหมายเลข 1 แทน boolean true บน iOS JSONDecoder จะโยน DecodingError.typeMismatch โดยค่าเริ่มต้น บน Android Gson จะพยายามแปลง ในขณะที่ Moshi และ kotlinx.serialization ต้องการอะแดปเตอร์ที่ชัดเจน วิธีแก้ไขคือใช้กลยุทธ์ lenient หรือตัวดีซีเรียลไลเซอร์แบบกำหนดเองสำหรับฟิลด์เฉพาะ

ฟิลด์ที่หายไปและ Nullable

เมื่อเซิร์ฟเวอร์ไม่รวมฟิลด์ที่เป็นทางเลือก โค้ดจะล้มเหลวพร้อมข้อผิดพลาด ฟิลด์ Optional ใน Swift และชนิด nullable ใน Kotlin แก้ปัญหาได้: หากฟิลด์เป็น null หรือไม่มีใน JSON คุณสมบัติจะได้รับ nil/null และแอปพลิเคชันทำงานต่อไป สำหรับฟิลด์บังคับ ควรตรวจสอบการมีอยู่ของฟิลด์เหล่านั้นในระดับไคลเอ็นต์ API ก่อนการดีซีเรียลไลเซชัน Moshi และ kotlinx.serialization ต้องการฟิลด์ทั้งหมดโดยค่าเริ่มต้น — การทำเครื่องหมาย nullable และค่าเริ่มต้นจะยกเลิกข้อจำกัดนี้

ความไม่เข้ากันของเวอร์ชัน API

การเปลี่ยนแปลงโครงสร้าง JSON บนเซิร์ฟเวอร์เป็นสาเหตุทั่วไปของความล้มเหลวในการใช้งานจริง แนวปฏิบัติมาตรฐานคือ การกำหนดเวอร์ชันสคีมา ผ่านฟิลด์ version ในออบเจกต์รากและการรองรับ 2-3 เวอร์ชันก่อนหน้าบนไคลเอ็นต์ kotlinx.serialization อนุญาตให้ประกาศหลายโมเดลสำหรับเวอร์ชันต่างๆ และเลือกโมเดลที่ถูกต้องตามฟิลด์ version หลังจากการแยกวิเคราะห์เริ่มต้นเป็น JsonElement การป้องกันเพิ่มเติมรวมถึง ignoreUnknownKeys สำหรับฟิลด์ใหม่และค่าเริ่มต้นสำหรับฟิลด์ที่อาจถูกลบ

ข้อผิดพลาดอาการไลบรารีที่มีการป้องกัน
Type mismatchDecodingError / ข้อยกเว้นkotlinx — coerceInputValues = true
ฟิลด์หายไปล้มเหลวเมื่อเข้าถึงMoshi — @Transient + default
รูปแบบวันที่ไม่ถูกต้องข้อผิดพลาดการถอดรหัสJSONDecoder — dateDecodingStrategy
ฟิลด์เกินไม่สนใจหรือล้มเหลวkotlinx — ignoreUnknownKeys = true
Null ในฟิลด์ที่ไม่ใช่ nullล้มเหลวขณะรันไทม์Moshi — lenient กับ @Nullable

การบันทึกข้อผิดพลาดการดีซีเรียลไลเซชัน เป็นแนวปฏิบัติบังคับในการใช้งานจริง ห่อ decode ใน do/catch บันทึก JSON ดิบและชนิดโมเดลที่คาดหวังใน Crashlytics หรือ Sentry ซึ่งจะช่วยระบุได้อย่างรวดเร็วว่าฟิลด์ใดของ API ใดเสียและในเวอร์ชันแอปใด หากไม่มีการบันทึก ข้อผิดพลาดการดีซีเรียลไลเซชันจะดูเหมือนความล้มเหลวลึกลับที่ไม่มีบริบท

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

การดีซีเรียลไลเซชันแตกต่างจากการแยกวิเคราะห์ (parsing) อย่างไร?

การแยกวิเคราะห์ คือการวิเคราะห์ข้อความที่มีโครงสร้างเป็นองค์ประกอบโดยไม่จำเป็นต้องสร้างโมเดลที่ระบุชนิด การดีซีเรียลไลเซชันเป็นกรณีเฉพาะของการแยกวิเคราะห์ซึ่งผลลัพธ์เป็นออบเจกต์ภาษาที่สมบูรณ์พร้อมชนิดคุณสมบัติที่รู้จัก การแยกวิเคราะห์สามารถเป็นแบบสตรีมมิ่ง การดีซีเรียลไลเซชันจะสร้างออบเจกต์ที่สมบูรณ์เสมอ

ควรเลือกไลบรารีดีซีเรียลไลเซชันใดสำหรับโปรเจกต์ Android ใหม่

สำหรับโปรเจกต์ Kotlin บริสุทธิ์ แนะนำ kotlinx.serialization — มันรวมเข้ากับคอมไพเลอร์ ไม่ใช้ reflection และรองรับ Kotlin Multiplatform สำหรับโปรเจกต์ Java ที่มีอยู่ — Moshi พร้อม code generation ควรปล่อย Gson ไว้สำหรับโปรเจกต์เดิมที่การแทนที่ต้องใช้ความพยายามอย่างมาก

จะทำอย่างไรหากเซิร์ฟเวอร์ส่ง snake_case แต่โมเดลใช้ camelCase?

บน iOS ให้ใช้ keyDecodingStrategy = .convertFromSnakeCase ใน JSONDecoder บน Android กับ kotlinx.serialization ให้ใช้ @SerialName สำหรับแต่ละฟิลด์ ใน Moshi ให้ใช้ @Json(name="field_name") หรือ JsonAdapter.Factory ทั่วโลก รูปแบบที่สอดคล้องกันในระดับโปรเจกต์เป็นแนวปฏิบัติที่ดีที่สุดที่ตกลงกันในสัญญา API

ทำไมการดีซีเรียลไลเซชันถึงล้มเหลวในสภาพแวดล้อมจริงแต่ไม่ใช่ในการพัฒนา?

สาเหตุที่พบบ่อยที่สุดคือ null ที่ไม่คาดคิด จากเซิร์ฟเวอร์บนฟิลด์ที่ประกาศเป็นฟิลด์บังคับ ในการพัฒนา เซิร์ฟเวอร์ส่งคืนข้อมูลที่สมบูรณ์ ในการใช้งานจริง ส่งคืนการตอบสนองที่สั้นลง วิธีแก้ไข: ทำเครื่องหมายฟิลด์ที่อาจหายไปทั้งหมดเป็น nullable (Kotlin) หรือ optional (Swift) ใช้ ignoreUnknownKeys และค่าเริ่มต้น

อะไรเร็วกว่า — Reflection หรือ Code generation ในการดีซีเรียลไลเซชัน?

Code generation (Moshi codegen, kotlinx.serialization, Codable) ทำงานเร็วกว่า reflection 2-4 เท่าในการวัดประสิทธิภาพของ Google นอกเหนือจากความเร็วแล้ว การสร้างโค้ดยังปลอดภัยกว่าตามชนิด ไม่ต้องการเมทาดาทาของคลาสในขณะรันไทม์ และข้อผิดพลาดชนิดจะถูกตรวจจับในเวลาคอมไพล์ ไม่ใช่ระหว่างการดีซีเรียลไลเซชัน

สรุป

  • การดีซีเรียลไลเซชัน เป็นกระบวนการพื้นฐานของการพัฒนามือถือที่กู้คืนออบเจกต์จาก JSON, XML หรือ Protobuf เพื่อใช้ในโค้ดแอปพลิเคชัน
  • iOS ใช้ JSONDecoder กับโปรโตคอล Codable ซึ่งให้การแปลงจาก JSON เป็นโมเดลโดยอัตโนมัติพร้อมกลยุทธ์คีย์และวันที่
  • Android มีสามเครื่องมือ: Gson (reflection), Moshi (reflection/codegen) และ kotlinx.serialization (การสร้างโดยคอมไพเลอร์ผ่าน @Serializable)
  • ข้อผิดพลาดทั่วไป — type mismatch, ฟิลด์หายไป, null ในฟิลด์ที่ไม่ใช่ null และความไม่เข้ากันของเวอร์ชัน API — ป้องกันได้ด้วยชนิด nullable, ignoreUnknownKeys และการกำหนดเวอร์ชัน
  • Code generation ปลอดภัยและเร็วกว่า reflection ดังนั้นจึงแนะนำสำหรับบิลด์ที่ใช้งานจริงของแอปพลิเคชันมือถือ
  • กลยุทธ์การแมป — keyDecodingStrategy บน iOS และ @SerialName บน Android แก้ปัญหาความไม่สอดคล้องของรูปแบบการตั้งชื่อระหว่างเซิร์ฟเวอร์และไคลเอ็นต์
  • อย่าลืมบันทึกข้อผิดพลาดการดีซีเรียลไลเซชันใน Crashlytics หรือ Sentry เพื่อการวินิจฉัยปัญหาในการใช้งานจริงอย่างรวดเร็ว

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

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

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

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