JSON to Kotlin Converter: แปลง JSON เป็น Kotlin Data Class ได้ในไม่กี่วินาที
เรียนรู้วิธีแปลง JSON sample เป็น Kotlin data class ที่รองรับ nested type, nullability และ serialization annotation ทำงานในเบราว์เซอร์ทั้งหมด
Table of Contents
JSON to Kotlin Converter: แปลง JSON เป็น Kotlin Data Class ได้ในไม่กี่วินาที
ถ้าคุณพัฒนาแอป Android, ดูแล backend ภาษา Kotlin หรือแชร์โค้ดด้วย Kotlin Multiplatform คุณต้องเจอ JSON แทบทุกวัน ไม่ว่าจะเป็น response จาก REST API, webhook หรือ payload ของ push notification ล้วนมาในรูปแบบ JSON และบ้านที่เหมาะสมที่สุดสำหรับข้อมูลเหล่านี้ในภาษา Kotlin ก็คือ data class แต่การพิมพ์ data class เองนั้นยุ่งยากและผิดพลาดง่าย คุณต้องจับคู่ key ให้ครบ ตัดสินใจว่า property ไหนเป็น nullable ห่อ object ที่ซ้อนอยู่เป็น type ของตัวเอง และจำให้ได้ว่า field ไหนต้องใส่ annotation @SerialName เพราะฝั่ง API ใช้ snake_case แต่โค้ดคุณใช้ camelCase
JSON to Kotlin Converter ช่วยกำจัดงานซ้ำซ้อนเหล่านี้ เพียงวาง JSON sample ลงในช่องด้านซ้าย เครื่องมือจะสร้าง Kotlin data class ที่พร้อมใช้งานให้ทางขวามือ ครบทั้ง nested type, nullability ที่ถูกต้อง และ serialization annotation แบบเลือกได้ ทุกอย่างทำงานแบบ 100% client-side ในเบราว์เซอร์ ข้อมูลที่ละเอียดอ่อนจึงไม่มีทางหลุดออกจากเครื่องของคุณ
บทความนี้จะพาไปดูวิธีใช้งานเครื่องมือ พร้อมแนวคิดเรื่อง nullability และ serial name เพื่อให้โค้ดที่ได้ใช้งานได้ทันทีในโปรเจกต์ของคุณ
ทำไมต้องใช้ JSON to Kotlin Converter?
ลด boilerplate ที่ต้องพิมพ์เอง response ที่มี 15 field พร้อม object ซ้อนข้างในหนึ่งตัว สร้าง Kotlin ได้ง่าย ๆ 60 บรรทัด และการพิมพ์เองมักมี typo ในชื่อ property ที่เพิ่งเจอตอนรัน ตัว converter สร้างโครงสร้างทั้งหมดเสร็จก่อนที่คุณจะพิมพ์ทันครึ่ง
ได้ nullability ที่ถูกต้องตั้งแต่แรก Kotlin บังคับให้คุณตัดสินใจตั้งแต่ต้นว่า property เป็น String หรือ String? เครื่องมือจะ mark property เป็น nullable เมื่อค่าหายไปหรือเป็น null ซึ่งเป็นสิ่งเดียวกันที่ deserializer จะตรวจสอบ
เชื่อม naming convention สองฝั่งให้อัตโนมัติ หลาย API ส่ง first_name มา แต่ Kotlin ที่ idiomatic อยากได้ firstName ตัว converter สร้าง annotation @SerialName ให้ได้ (เลือก annotation style ได้) เพื่อให้ชื่อ wire ถูกต้องและชื่อ property สะอาดไปพร้อมกัน
ข้อมูลส่วนตัวไม่หลุดออกไป เพราะทำงานฝั่ง client ล้วน ๆ sample ที่คุณวางจะไม่ถูกส่งหรือเก็บที่ใดเลย ซึ่งสำคัญมากเมื่อคุณทำงานกับข้อมูลผู้ใช้ token หรือรูปแบบ API ที่ยังไม่เปิดตัว
อัปเดตตาม API ได้ทันที เมื่อมี field เพิ่มหรือเปลี่ยนชื่อ แค่วาง sample ใหม่แล้ว generate ซ้ำ การดูแล model จึงกลายเป็นการ copy-paste ไม่กี่วินาที แทนที่จะนั่งแก้ทีละบรรทัด
ฟีเจอร์หลัก
| ฟีเจอร์ | ทำอะไร | ทำไมจึงสำคัญ |
|---|---|---|
| สร้าง data class | แปลง JSON sample เป็น Kotlin data class | ลดการพิมพ์เองและข้อผิดพลาดการตั้งชื่อ |
| รองรับ nested type | ห่อ object และ array ที่ซ้อนกันเป็น class ของตัวเอง | สะท้อน payload จริงได้ครบถ้วน |
| ตรวจ nullability | mark property เป็น nullable เมื่อค่าหายหรือเป็น null | ป้องกัน crash จากข้อมูลไม่ครบ |
| Serialization annotation | สร้าง @SerialName ให้ key ที่ต้องเปลี่ยนชื่อ เลือก style ได้ | แยกชื่อ wire ออกจากชื่อ property |
| ทำงานฝั่ง client | parsing และการสร้างโค้ดเกิดขึ้นในเบราว์เซอร์ทั้งหมด | ปลอดภัยกับ payload ส่วนตัว |
| ผลลัพธ์พร้อมวาง | ได้ Kotlin ที่จัดรูปแบบตาม convention แล้ว | copy ลง IDE แล้ว build ได้ทันที |
หมายเหตุสั้น ๆ เพิ่มเติม:
- ผลลัพธ์เป็นไปตาม convention ของ Kotlin — property แบบ val, ชื่อ class แบบ PascalCase, ชื่อ property แบบ camelCase — อ่านลื่นเหมือนโค้ดที่นักพัฒนาเขียนเอง
- array ที่มี object เป็นสมาชิกจะได้ data class เพิ่มสำหรับ element แต่ละแบบ และตัวเลือก annotation style ช่วยให้ผลลัพธ์เข้ากับ serialization library ที่โปรเจกต์ใช้อยู่
วิธีใช้งาน
- วาง JSON sample คัดลอก response ตัวอย่างจาก API หรือ fixture ของคุณมาวางในช่อง input โดยเลือก sample ที่มี field ครบทุกอันที่สนใจจะได้ผลดีที่สุด
- ตรวจผลการ parse เครื่องมือตรวจ JSON ให้ระหว่างพิมพ์ ถ้ามี comma เกินหรือ key ไม่ได้ใส่ quote จะเห็นทันที ไม่ต้องรอไปเจอตอน build
- เลือกตัวเลือก annotation ถ้า key เป็น snake_case หรือต่างจากชื่อ property ที่ต้องการ ให้เปิด serialization annotation แล้วเลือก style ที่โปรเจกต์ใช้ เช่น @SerialName ของ kotlinx
- ตรวจ Kotlin ที่ได้ ดูชื่อ class ยืนยันว่า property ไหนถูก mark เป็น nullable และ object ที่ซ้อนอยู่กลายเป็น type ของตัวเองครบหรือไม่
- คัดลอกลงโปรเจกต์ วาง class ลง package ที่เหมาะสม เพิ่ม serialization dependency ถ้ายังไม่มี แล้วเริ่ม parse response จริงได้เลย
ทั้งวงจรใช้เวลาไม่ถึงหนึ่งนาที ทำให้การ generate model ใหม่ทุกครั้งที่ API เปลี่ยนเป็นเรื่องสมจริง
เจาะลึก Nullability และ Serial Name
จุดนี้แหละที่ทำให้การแปลง JSON เป็น Kotlin น่าสนใจ เพราะระบบ type ของ Kotlin ให้ความสำคัญกับ nullability อย่างชัดเจน และการ deserialize คือสถานที่ที่ความเข้มงวดนี้คุ้มค่าที่สุด
String กับ String?
ใน Kotlin ไม่มี null แบบแอบแฝง property แบบ String เก็บ null ไม่ได้ ส่วน String? เก็บได้ เมื่อ converter เห็น key ที่เป็น null ชัดเจน หรือมีอยู่ใน object หนึ่งแต่หายไปจากอีก object หนึ่ง มันจะสร้าง property นั้นเป็น nullable ซึ่งสะท้อนความจริงบน wire: ถ้า API ส่ง middle_name มาไม่ได้ ใน data class ต้องเป็น val middleName: String? = null ไม่เช่นนั้น deserializer จะ throw การตัดสินใจนี้ถูกฝังไว้ใน declaration ตั้งแต่ต้น แทนที่จะไปเจอตอนเกิด crash ใน production
Serial Name สำหรับชื่อบน wire
Kotlin นิยม camelCase แต่หลาย API พูดจากันด้วย snake_case @SerialName คือคำตอบมาตรฐานของ kotlinx.serialization โดยบอก serializer ว่า "property นี้ชื่อ firstName ใน Kotlin แต่ให้มองหา first_name ใน JSON" converter จะสร้าง annotation นี้ให้ทุก key ที่ต้องเปลี่ยนชื่อ ทำให้ชื่อ property ในโค้ดเป็นสากลและชื่อจริงบน wire ถูกต้องไปพร้อมกันโดยไม่ต้องจำเอง
Collection และ nested data class
array จะแปลงเป็น List ของ element type และ array ที่มี object เป็นสมาชิกจะได้ data class แยกสำหรับรูปร่างของ element payload ที่ซ้อนกันลึกหลายชั้นจึงได้กลุ่ม class เล็ก ๆ ที่อ่านง่าย แทนที่จะเป็น class เดียวใหญ่เต็มไปด้วย map หลวม ๆ
เทียบ sample กับผลลัพธ์
สมมติว่า input เป็นแบบนี้:
{
"user_id": 4821,
"display_name": "Nina Chen",
"middle_name": null,
"email_verified": true,
"orders": [{ "order_id": "A-104", "total": 59.9 }]
}
converter จะสร้างให้ประมาณนี้:
@Serializable
data class User(
@SerialName("user_id")
val userId: Long,
@SerialName("display_name")
val displayName: String,
@SerialName("middle_name")
val middleName: String? = null,
@SerialName("email_verified")
val emailVerified: Boolean,
@SerialName("orders")
val orders: List<Order>
)
@Serializable
data class Order(
@SerialName("order_id")
val orderId: String,
@SerialName("total")
val total: Double
)
ทุกเรื่องระดับ wire — key ที่ต้องเปลี่ยนชื่อ, middle name ที่เป็น nullable, Order ที่ซ้อนอยู่ — ถูกจับไว้ใน declaration ทั้งหมด ไม่ใช่ตรรกะที่ต้องไปตรวจตอนรัน
กรณีใช้งานจริง
Model ของแอป Android
นักพัฒนา Android คือกลุ่มที่เจอปัญหานี้ใกล้ที่สุด แอปที่ยิงหลาย endpoint จะสะสม model class หลายสิบตัวที่ต้องตรงกับชื่อและความ optional ของ backend เป๊ะ ๆ การ generate จาก response จริงช่วยให้ model layer ก้าวตามเซิร์ฟเวอร์ทัน ซึ่งต่างจาก MissingFieldException ใน crash report อย่างสิ้นเชิง
DTO ฝั่ง Kotlin backend
บริการ Kotlin ฝั่งเซิร์ฟเวอร์มักได้รับ JSON จากภายนอก ไม่ว่าจะเป็น payment webhook, API ของพาร์ทเนอร์ หรือระบบเก่า DTO สำหรับ payload เหล่านี้ต้องสะท้อน contract ของภายนอก ไม่ใช่ domain ภายใน การ generate จาก sample ที่จับไว้ให้ boundary layer ที่แม่นยำ พร้อม map เข้า domain type ต่อได้
โค้ด shared บน Kotlin Multiplatform
ด้วย Kotlin Multiplatform data class ชุดเดียวใช้ได้ทั้ง Android, iOS, desktop และ web การแก้ model หนึ่งครั้งจึงช่วยทุกแพลตฟอร์มพร้อมกัน การ generate model shared จาก sample หลักของ API ทำให้ทั้งผลิตภัณฑ์ใช้นิยามของ User หรือ Order เดียวกัน
เอกสารอ้างอิงตอนย้าย API
เวลาย้าย integration ไปยัง API เวอร์ชันใหม่ การมี class ของ payload เก่าและใหม่วางเคียงกันช่วยให้เห็น field ที่เปลี่ยนชื่อและ type ที่เปลี่ยนชนิดได้ทันที ใช้คู่กับ JSON formatter เพื่อเทียบ sample ใหญ่ ๆ แล้วเช็กลิสต์การ migrate แทบเขียนตัวเองเสร็จ
แนวทางปฏิบัติที่ดี
- เลือกระหว่าง default value กับ nullable ให้เป็น property แบบ nullable บอกว่า "ค่านี้อาจไม่มา" ส่วน default value บอกว่า "ถ้าไม่มาให้ทำแบบนี้" การใช้ร่วมกันให้ทั้งความปลอดภัยและความสะดวกตอนสร้าง object
- เก็บชื่อ wire ไว้ใน annotation อย่าเปลี่ยนชื่อ key ของ JSON ใน data class ให้ @SerialName รับผิดชอบ mapping เพื่อให้ชื่อ property เดินตามสไตล์ Kotlin ได้ตลอด แม้ API จะเปลี่ยน
- generate ซ้ำทุกครั้งที่ API เปลี่ยน ถือว่าไฟล์ที่ได้เป็นผลลัพธ์ของ sample วาง response ใหม่แล้ว diff ผลลัพธ์ ดีกว่าแก้มือแล้วหวังว่าจะไม่พลาด
- ทดสอบกับ payload จริง ลองวาง response ที่มี null, field หาย และ array ว่าง ๆ model ที่สร้างจาก JSON สวยหรูมักมอง nullability สดใสเกินจริง
- ตัด sample ให้เหลือ object ตัวแทนหนึ่งตัว สำหรับ array ของ item ใช้ element เดียวก็พอ sample เล็กช่วยให้ชื่อ class สะอาด
- จัดรูปแบบ input ที่เพี้ยนก่อน ถ้า sample มาแบบ minified หรือ escape แปลก ๆ ลองผ่าน JSON formatter ก่อนเพื่อให้ converter เห็นโครงสร้างที่สะอาด
พร้อมสร้าง Kotlin Model แล้วหรือยัง?
เลิกพิมพ์ data class ด้วยมือได้แล้ว เปิด JSON to Kotlin Converter วาง sample แล้วคัดลอก Kotlin ที่ idiomatic — ครบทั้ง nested type, nullability และ serialization annotation — ภายในไม่กี่วินาที ใช้ฟรี ไม่ต้องสมัครสมาชิก และไม่มีการส่งข้อมูลของคุณไปที่ใด
เครื่องมืออื่น ๆ ที่น่าสนใจ:
- JSON Formatter — จัดรูปแบบ ตรวจสอบ และย่อขนาด JSON ก่อนหรือหลังสร้าง model
- JSON to Swift Converter — สร้าง Swift struct ที่เทียบเท่ากัน เมื่อ API เดียวกันต้องป้อนแอป iOS ด้วย
- OpenAPI to TypeScript Converter — สร้าง interface แบบมี type จาก OpenAPI spec สำหรับ web client ของคุณ
เครื่องมือที่ประหยัดเวลาขนาดนี้จะมีประโยชน์ก็ต่อเมื่อคุณหาเจอ — bookmark JSON to Kotlin Converter ไว้ แล้วใช้ data class ที่ generate แล้วเป็นจุดเริ่มต้นของทีมคุณ
คำถามที่พบบ่อย
ถ: JSON sample ของฉันถูกอัปโหลดไปเซิร์ฟเวอร์หรือไม่?
ตอบ: ไม่ converter parse และสร้าง Kotlin ทั้งหมดในเบราว์เซอร์ของคุณ ไม่มีการส่ง บันทึก หรือเก็บข้อมูลที่ใดเลย จึงปลอดภัยแม้กับ payload ที่ต้องยืนยันตัวตนหรือเป็นความลับ
ถ: โค้ดที่ได้ใช้ serialization library ตัวไหน?
ตอบ: ผลลัพธ์เป็น Kotlin data class ธรรมดา โดยมี annotation เสริมตามสไตล์ kotlinx.serialization รวมถึง @SerialName สำหรับ key ที่ต้องเปลี่ยนชื่อ และตัวเลือก annotation style ช่วยปรับให้เข้ากับ convention ของโปรเจกต์คุณ
ถ: เครื่องมือตัดสินใจว่า property ไหนเป็น nullable อย่างไร?
ตอบ: property จะเป็น nullable เมื่อค่าใน sample เป็น null ชัดเจน หรือ field นั้นหายไปจาก object ที่ตัวอื่นในตำแหน่งเดียวกันมี หาก API จริงของคุณมีความ optional ต่างจาก sample สามารถแก้ type ที่ได้เพิ่มได้ทันที
ถ: รองรับ object ที่ซ้อนกันลึก ๆ และ array ของ object ไหม?
ตอบ: รองรับครับ object ที่ซ้อนกันจะกลายเป็น data class ของตัวเอง และ array แปลงเป็น List ของ element type payload ที่ซ้อนหลายชั้นจึงได้กลุ่ม class เล็ก ๆ ที่เป็นระเบียบ
ถ: ใช้ฟรีจริงหรือ?
ตอบ: ฟรีทั้งหมด ไม่มีการสมัคร ไม่มีโควตา และเพราะทำงานในเครื่องล้วน ๆ คุณยังใช้แบบออฟไลน์ได้เมื่อโหลดหน้าเว็บแล้ว