การทำซีเรียลไลซ์คือกระบวนการแปลงวัตถุหรือโครงสร้างข้อมูลไปยังรูปแบบเรียงลำดับที่เหมาะสมสำหรับการส่งผ่านเครือข่ายหรือการเก็บไฟล์ กระบวนการย้อนกลับ การทำดีซีเรียลไลซ์จะคืนสภาพข้อมูลไปสู่สภาพเดิม ตาม MDN Web Docs การทำซีเรียลไลซ์จำเป็นสำหรับการติดต่อระหว่างกระบวนการใดๆ การทำซีเรียลไลซ์ เป็นรากฐานของ REST API แคชชิ่งและการแลกเปลี่ยนข้อมูลระหว่างส่วนประกอบแอปพลิเคชัน
ข้อสำคัญ
การทำซีเรียลไลซ์ คือกระบวนการแปลงอ็อบเจ็กต์ที่อยู่ในหน่วยความจำ RAM ไปเป็นลำดับเชิงเส้นของไบต์หรืออักขระที่สามารถส่งผ่านเครือข่าย บันทึกไปยังไฟล์ หรือส่งต่อไปยังกระบวนการอื่น หากไม่มีการทำซีเรียลไลซ์ การสื่อสารผ่านเครือข่าย การคงสภาพและการโต้ตอบระหว่างกระบวนการจะเป็นไปไม่ได้
การทำซีเรียลไลซ์ประกอบด้วยสองกระบวนการที่ตรงกันข้าม กระบวนการไปข้างหน้า (การทำซีเรียลไลซ์) จะอัดแพ็คเกจข้อมูลเป็นรูปแบบสำหรับการส่ง กระบวนการย้อนกลับ (การทำดีซีเรียลไลซ์) จะคืนสภาพข้อมูลไปเป็นอ็อบเจ็กต์ การทำดีซีเรียลไลซ์มีความสำคัญต่อความปลอดภัย: ข้อมูลนำเข้าที่ไม่ถูกต้องอาจนำไปสู่ช่องโหว่ในแอปพลิเคชัน
ในการพัฒนาแอปพลิเคชันมือถือ การทำซีเรียลไลซ์ถูกใช้ทุกหน: การส่งคำขอไปยังเซิร์ฟเวอร์และการประมวลผลการตอบสนอง การบันทึกสภาพแอปพลิเคชันเมื่อหมุนหน้าจอ แคชข้อมูลบนดิสก์ และการส่งต่อข้อมูลระหว่างหน้าจอผ่าน Intent (Android) หรือ Segue (iOS)
รูปแบบการทำซีเรียลไลซ์ แบ่งออกเป็นข้อความและไบนารี รูปแบบข้อความ (JSON, XML) อ่านได้โดยมนุษย์และไม่ต้องการเครื่องมือในการดู รูปแบบไบนารี (Protobuf, FlatBuffers, MessagePack) กะทัดรัดและเร็วกว่า แต่อ่านไม่ได้หากไม่มีการทำดีซีเรียลไลซ์ การเลือกรูปแบบเป็นการประนีประนอมระหว่างประสิทธิภาพและความสะดวกในการแก้ไขปัญหา
นอกจาก JSON, XML และ Protobuf ยังมีรูปแบบเฉพาะทาง: FlatBuffers จาก Google สำหรับเกมและ AR, MessagePack — ทางเลือกไบนารีที่กะทัดรัดของ JSON, Avro จาก Apache สำหรับข้อมูลขนาดใหญ่ใน Kafka, YAML — รูปแบบการตั้งค่าที่รองรับความคิดเห็น
| รูปแบบ | ประเภท | โครงสร้าง | ขนาด | ความเร็ว |
|---|---|---|---|---|
| JSON | ข้อความ | เลือกได้ | ปานกลาง | ปานกลาง |
| XML | ข้อความ | XSD | ใหญ่ | ต่ำ |
| Protobuf | ไบนารี | บังคับ | เล็ก | สูง |
| FlatBuffers | ไบนารี | บังคับ | เล็ก | สูงสุด |
| MessagePack | ไบนารี | ไม่ | เล็ก | สูง |
| Avro | ไบนารี | JSON Schema | เล็ก | สูง |
การทำซีเรียลไลซ์ บนแพลตฟอร์มมือถือมีลักษณะเฉพาะของตัวเอง: ปริมาณทราฟิกที่จำกัด โปรเซสเซอร์ที่อ่อนแรงและความจำเป็นในการรักษาสภาพเมื่อหมุนหน้าจอ บน Android ใช้ Gson, Moshi, Kotlinx Serialization บน iOS — Codable, JSONSerialization, PropertyListEncoder การเลือกไลบรารีที่ถูกต้องมีผลกระทบอย่างมากต่อประสิทธิภาพของแอปพลิเคชัน
Kotlinx Serialization เป็นไลบรารีทันสมัยจาก JetBrains สำหรับ Kotlin Multiplatform Mobile รองรับ JSON, Protobuf, CBOR และรูปแบบที่กำหนดเอง การสร้างโค้ดเกิดขึ้นในระหว่างการคอมไพล์ผ่านปลั๊กอิน Kotlin Serialization ซึ่งรับประกันประสิทธิภาพสูงโดยไม่ต้องใช้การสะท้อนกลับ
ไลบรารี Kotlinx Serialization ใช้คำอธิบาย @Serializable สำหรับคลาสและปลั๊กอินคอมไพเลอร์สำหรับสร้างตัวทำซีเรียลไลซ์ ซึ่งรับประกันประสิทธิภาพสูงและความปลอดภัยของชนิด รูปแบบเริ่มต้นเป็น JSON แต่รูปแบบอื่นๆ ได้รับการสนับสนุนผ่านโมดูลเพิ่มเติม
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
@Serializable
data class Project(
val id: Int,
val name: String,
val platforms: List<String>,
val active: Boolean
)
val json = Json {
prettyPrint = true
ignoreUnknownKeys = true
encodeDefaults = true
}
fun main() {
val project = Project(1, "MobileApp",
listOf("Android", "iOS"), true)
// การซีเรียลไลซ์
val jsonString = json.encodeToString(project)
// การดีซีเรียลไลซ์
val restored = json.decodeFromString<Project>(jsonString)
}
โปรโตคอล Codable เป็นกลไกการทำซีเรียลไลซ์แบบในตัวของ Swift โปรโตคอลนี้รวมโปรโตคอล Encodable (การทำซีเรียลไลซ์) และ Decodable (การทำดีซีเรียลไลซ์) JSONEncoder และ JSONDecoder จัดการโครงสร้างซ้อนกัน อาร์เรย์ ค่าตัวเลือกและคีย์ที่กำหนดเองผ่าน CodingKeys โดยอัตโนมัติ
import Foundation
struct AppConfig: Codable {
let appName: String
let version: String
let features: [String]
let isProduction: Bool
}
let config = AppConfig(
appName: "MyApp",
version: "2.1.0",
features: ["push", "analytics", "offline"],
isProduction: true
)
let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
guard let data = try? encoder.encode(config) else { return }
let jsonString = String(data: data, encoding: .utf8)
ประสิทธิภาพของรูปแบบการทำซีเรียลไลซ์ถูกประเมินโดยสามเมตริก: ขนาดข้อความ ความเร็วในการทำซีเรียลไลซ์และความเร็วในการทำดีซีเรียลไลซ์ สำหรับแอปพลิเคชันมือถือ ทั้งสามมีความสำคัญ: ขนาดมีผลต่อปริมาณทราฟิกและเวลาโหลด ความเร็วมีผลต่อการตอบสนองของส่วนติดต่อผู้ใช้และเวลาเริ่มต้นแอปพลิเคชัน
Protobuf และ FlatBuffers แสดงผลลัพธ์ที่ดีที่สุดโดยการแสดงผลแบบไบนารี FlatBuffers เป็นเวทร์เพราะไม่ต้องการขั้นตอนการทำดีซีเรียลไลซ์แยกต่างหาก — ข้อมูลถูกอ่านโดยตรงจากบัฟเฟอร์ไบนารีโดยไม่ต้องแปลงรูป ทำให้เหมาะสำหรับเกมและแอปพลิเคชัน AR ที่ต้องการหน่วงเวลาน้อยที่สุด JSON ยังคงเป็นรูปแบบที่ได้รับความนิยมมากที่สุดสำหรับ REST API แม้ว่าจะมีประสิทธิภาพต่ำกว่า เนื่องจากความง่ายและความเป็นสากล
| สถานการณ์ | รูปแบบที่แนะนำ | เหตุผล |
|---|---|---|
| REST API | JSON | ความเป็นสากล, อ่านง่าย, การสนับสนุน |
| ไมโครเซิร์ฟวิส | Protobuf | ความกะทัดรัด, ความเร็ว, gRPC |
| เกม / AR | FlatBuffers | Zero-copy, หน่วงเวลาน้อยที่สุด |
| ข้อมูลขนาดใหญ่ | Avro | ความเข้ากันได้กับ Kafka และ Hadoop |
| การตั้งค่า | YAML | ความคิดเห็น, อ่านง่าย |
| เลเอาต์ Android | XML | มาตรฐานแพลตฟอร์ม |
การทดสอบเชิงปฏิบัติบนชุดข้อมูลของผู้ใช้ 1,000 รายการแสดงว่า: Protobuf สร้างข้อความขนาด 12 KB (JSON — 85 KB, XML — 120 KB) เวลาในการทำซีเรียลไลซ์: Protobuf — 2 ms, JSON — 8 ms, XML — 25 ms ตัวเลขเหล่านี้ทำให้รูปแบบไบนารีเป็นที่ต้องการสำหรับระบบโหลดสูงและแอปพลิเคชันมือถือที่มีปริมาณทราฟิกจำกัด
ตัวอย่างแสดงการทำซีเรียลไลซ์ของอ็อบเจ็กต์เดียวกันในรูปแบบต่างๆ ซึ่งช่วยเปรียบเทียบขนาดและความอ่านได้อย่างเป็นรูปธรรม อ็อบเจ็กต์ User แบบเดียวกันจะถูกทำซีเรียลไลซ์เป็น JSON, XML และ Protobuf — เห็นได้อย่างชัดเจนว่า JSON กะทัดรัดกว่า XML และ Protobuf กะทัดรัดที่สุดและอ่านไม่ได้
JSON — ไวยากรณ์แบบน้อยที่สุด คีย์อยู่ในเครื่องหมายอัญประกาศ ค่าของหลายประเภท มีขนาด 80 อักขระ อ่านง่ายมาก โครงสร้างทางสายตาชัดเจน เหมาะสำหรับ API ที่ความเร็วในการพัฒนาและแก้ไขปัญหามีความสำคัญ
XML — แต่ละองค์ประกอบประกอบด้วยแท็กเปิดและแท็กปิด มีขนาด 150 อักขระ อ่านได้ปานกลาง โครงสร้างเข้มงวด เหมาะสำหรับกระบวนการเอกสารและระบบที่ต้องการตรวจสอบ XSD
Protobuf — ไบนารี 32 ไบต์สำหรับข้อมูลนี้ อ่านไม่ได้ — ต้องการการทำดีซีเรียลไลซ์เพื่อดู ขนาดที่เล็กที่สุดทำให้เหมาะสำหรับระบบโหลดสูงและแอปพลิเคชันมือถือ
{
"id": 42,
"name": "IT Sectr",
"email": "team@itsectr.com",
"role": "admin",
"active": true
}
<user>
<id>42</id>
<name>IT Sectr</name>
<email>team@itsectr.com</email>
<role>admin</role>
<active>true</active>
</user>
แนวปฏิบัติที่ดีช่วยหลีกเลี่ยงข้อผิดพลาดทั่วไประบุและเลือกกลยุทธ์การทำซีเรียลไลซ์ที่ถูกต้องสำหรับโปรเจค การปฏิบัติตามคำแนะนำเหล่านี้ช่วยพัฒนาประสิทธิภาพ ความปลอดภัยและการบำรุงโค้ด
ความปลอดภัยของการทำซีเรียลไลซ์ เป็นประเด็นที่สำคัญอย่างยิ่ง โดยเฉพาะอย่างยิ่งเมื่อทำดีซีเรียลไลซ์ข้อมูลจากแหล่งที่ไม่น่าเชื่อถือ การโจมตีการทำดีซีเรียลไลซ์สามารถนำไปสู่การดำเนินการโค้ดแบบระยะไกล (RCE) ซึ่งเป็นหนึ่งในช่องโหว่แอปพลิเคชันที่อันตรายที่สุดในแอปพลิเคชันเว็บและมือถือ กรณีที่รู้จักกันดีที่สุดเกี่ยวข้องกับ Java Serializable และ Python pickle
Protobuf และ JSON มีการป้องกันในตัวต่อการโจมตีเหล่านี้ เพราะมันทำงานกับข้อมูลเท่านั้น ไม่ใช่อ็อบเจ็กต์ใดๆ ในทางกลับกัน Java Serializable สามารถคืนสภาพคลาสใดๆ ที่มีอยู่ใน classpath ซึ่งทำให้เป็นอันตรายสำหรับการรับข้อมูลจากแหล่งภายนอก บน Android แนะนำให้ใช้ Kotlinx Serialization หรือ Moshi แทนที่จะใช้ Java Serialization มาตรฐาน
มาตรการด้านความปลอดภัยเพิ่มเติม: กำหนดขอบเขตขนาดข้อมูลนำเข้า ตรวจสอบโครงสร้างก่อนการทำดีซีเรียลไลซ์ อย่าเชื่อถือ Content-Type จากส่วนหัว HTTP ใช้รายชื่อที่อนุญาตสำหรับคลาสที่ได้รับอนุญาต อัปเดตไลบรารีการทำซีเรียลไลซ์เป็นประจำ เพราะช่องโหว่แบบนี้ถูกค้นพบและแก้ไขเป็นประจำ
คำถามที่พบบ่อย
การทำซีเรียลไลซ์ แปลงอ็อบเจ็กต์เป็นลำดับของไบต์ ในขณะที่ marshalling ส่งต่อข้อมูลระหว่างพื้นที่อยู่ที่แตกต่างกันโดยยังคงรักษาชนิดและโครงสร้างไว้ Marshalling รวมการทำซีเรียลไลซ์เป็นส่วนหนึ่งของกระบวนการ แต่อาจรวมถึงการเข้ารหัสอ้างอิงและการจัดการหน่วยความจำ
FlatBuffers จาก Google ให้ความเร็วสูงสุดด้วยการทำดีซีเรียลไลซ์แบบ zero-copy — ข้อมูลถูกอ่านโดยตรงจากบัฟเฟอร์ไบนารีโดยไม่ต้องแปลงรูป Protobuf อยู่อันดับสอง JSON อยู่อันดับสาม XML เป็นรูปแบบที่ช้าที่สุดในรูปแบบที่แพร่หลาย
Kotlinx Serialization เป็นตัวเลือกที่ดีที่สุดสำหรับโปรเจค Kotlin ใหม่: การสร้างในคอมไพล์, การสนับสนุน Kotlin Multiplatform, null safety Moshi เป็นตัวเลือกที่ดีสำหรับโปรเจค Java มีประสิทธิภาพมากกว่า Gson Gson เป็นไลบรารีที่ง่ายที่สุดสำหรับเริ่มต้น แต่ช้ากว่าและใช้การสะท้อนกลับ
การอ้างอิงแบบวงกลมนำไปสู่การเรียกซ้ำไม่สิ้นสุดในระหว่างการทำซีเรียลไลซ์ วิธีแก้: ใช้ การอ้างอิง ID แทนการอ้างอิงโดยตรงไปยังอ็อบเจ็กต์ ใช้อะแดปเตอร์การทำซีเรียลไลซ์เฉพาะทาง (ตัวอย่าง @JsonIgnore ใน Jackson) หรือออกแบบโมเดลข้อมูลใหม่เพื่อกำจัดวงกลม
ใช่ โดยเฉพาะการทำดีซีเรียลไลซ์ข้อมูลที่ไม่น่าเชื่อถือ ช่องโหว่การทำดีซีเรียลไลซ์สามารถนำไปสู่การดำเนินการโค้ดแบบระยะไกล คำแนะนำ: อย่าทำดีซีเรียลไลซ์ข้อมูลจากแหล่งที่ไม่น่าเชื่อถือ ใช้รายชื่อที่อนุญาตของคลาสในระหว่างการทำดีซีเรียลไลซ์และตรวจสอบโครงสร้างข้อมูลก่อนการประมวลผล
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ