JSON Toolkit

JSON, TOML, YAML หรือ CSON: การเลือกไฟล์กำหนดค่า

สรุปสำคัญ: ไฟล์กำหนดค่าต้องการ comment วันที่ และข้อความหลายบรรทัด ซึ่งเป็นจุดที่ JSON ทำไม่ได้ เปรียบเทียบ JSON, TOML, YAML และ CSON และดูว่าการแปลงสูญเสียอะไรเสมอ

ผู้เริ่มต้นอ่านประมาณ 9 นาทีเผยแพร่ 2026-10-31อัปเดต 2026-10-31
ภาพหน้าปกเปรียบเทียบรูปแบบ JSON, TOML, YAML และ CSON

สรุปสั้น: ใช้ JSON สำหรับการแลกเปลี่ยนระหว่างเครื่อง และเลือก TOML หรือ YAML สำหรับไฟล์กำหนดค่าที่มนุษย์ดูแลตามระบบนิเวศ (YAML สำหรับ Kubernetes และ CI, TOML สำหรับโครงสร้างแบบแบนหรือวันที่โดยธรรมชาติ); ถอยไปใช้ JSONC เฉพาะเมื่อไม่แน่ใจว่าตัวอ่านรองรับภาษาถิ่น

JSON มีอยู่เพื่อเครื่องแลกเปลี่ยนข้อมูล ส่วนไฟล์กำหนดค่าถูกเขียนโดยคนเพื่อคน ผสมสองอย่างเข้าด้วยกันคุณจะได้ config.json ที่ใส่ comment ไม่ได้และไม่มีใครกล้าตัดอะไรออก

1. เริ่มจากไฟล์สองชนิดที่ต่างกัน

การแลกเปลี่ยนข้อมูลและการกำหนดค่าไม่ได้มีเป้าหมายเดียวกัน แม้คนคนเดียวกันมักเขียนทั้งสองอย่างบนเครื่องเดียวกัน

มิติ การแลกเปลี่ยนข้อมูล การกำหนดค่า
ใครเขียน โปรแกรมที่ serialize ค่า มนุษย์ หรือมนุษย์ที่แก้ไขเอาต์พุตที่สร้างขึ้น
ใครอ่าน โปรแกรมของคนอื่น โปรแกรมของคุณเอง
อะไรสำคัญ ไม่กำกวม, ขนาด, ความเร็ว parse อ่านง่าย, comment, diff ที่รีวิวได้
ความถี่ในการเปลี่ยน ทุกคำขอ เป็นครั้งคราว พร้อมการรีวิว
ต้นทุนของข้อผิดพลาด response 500 service ที่ไม่ยอมเริ่มทำงาน

JSON ได้คะแนนเกือบเต็มในคอลัมน์ซ้าย: ไวยากรณ์มินิมัล, parser มีทุกภาษา และการไม่มี comment หมายถึงไม่มีปัญหา "comment ห่างเหินจากค่า" ในคอลัมน์ขวา ความเข้มงวดของมันคือแรงเสียดทานล้วน: ไม่มี comment, ไม่มี trailing comma, ไม่มีวันที่ และข้อความหลายบรรทัดต้องยุบเป็นบรรทัดเดียวด้วย \n

2. ผู้แข่งขันสี่รายและไวยากรณ์ของพวกมัน

  • JSON: นิยามโดย RFC 8259 และ ECMA-404 มีชนิดค่าหกแบบพอดี: object, array, string, number, boolean และ null เป็นมาตรฐานการแลกเปลี่ยนโดยพฤตินัยและเป็นรูปแบบเดียวที่ไม่ต้องตัดสินใจเลือก
  • TOML: สร้างโดย Tom Preston-Werner โดย v1.0.0 เผยแพร่ในเดือนมกราคม 2021 เป้าหมายที่ประกาศไว้คือรูปแบบกำหนดค่ามินิมัลที่มีความหมายชัดเจนและ map กับ hash table อย่างไม่กำกวม Cargo.toml และ pyproject.toml ใช้มันเป็นค่าเริ่มต้น
  • YAML: สเปกปัจจุบันคือ 1.2.2 การย่อหน้าแสดงลำดับชั้น และรองรับ comment, anchor และหลายเอกสาร Kubernetes manifest, GitHub Actions และ Ansible ต่างพึ่งมัน ด้วยต้นทุนเป็นสเปกขนาดใหญ่และความแตกต่างระหว่าง implementation
  • CSON: CoffeeScript Object Notation ซึ่งเขียน configuration ด้วย object literal ของ CoffeeScript config.cson ของ Atom เคยใช้มัน มันรองรับ comment, คีย์ที่ไม่ใส่เครื่องหมายคำพูด และ trailing comma แต่ระบบนิเวศของมันไม่เคยออกจากโลก JavaScript

2.1 เปรียบเทียบความสามารถ

ความสามารถ JSON TOML YAML CSON
Comment ✗ ✓ # ✓ # ✓ #
Trailing comma ✗ ✓ (array, inline table) ✓ (flow collection) ✓
คีย์ที่ไม่ใส่เครื่องหมายคำพูด ✗ ✓ ✓ ✓
วันที่-เวลาโดยธรรมชาติ ✗ (string เท่านั้น) ✓ ชนิดวันที่-เวลาสี่แบบ ✓ (parse อัตโนมัติใน 1.1) ✗
String หลายบรรทัด ✗ (escape \n) ✓ """ และ ''' ✓ block และ folded scalar ✓ heredoc
ช่วงจำนวนเต็ม ไม่จำกัดในสเปก แต่เป็น double ในทางปฏิบัติ 64 บิตมีเครื่องหมาย ต้องไม่สูญเสีย ความแม่นยำตามอำเภอใจบวก .inf/.nan ตาม JavaScript
การซ้อน วงเล็บปีกกาและวงเล็บเหลี่ยม table, array ของ table, dotted key การย่อหน้า การย่อหน้า
ไวต่อการย่อหน้า ✗ ✗ ✓ ✓
null ✓ ✗ ✓ ✓
การครอบคลุมเครื่องมือ ทุกภาษา ภาษากระแสหลัก ทุกภาษา แต่ implementation ต่างกัน JavaScript เท่านั้น

สองช่องที่ควรสังเกต TOML ไม่มี null ซึ่งเป็นความล้มเหลวที่พบบ่อยที่สุดเมื่อแปลงจาก JSON พฤติกรรม "วันที่โดยธรรมชาติ" ของ YAML หมายความว่า parser 1.1 เปลี่ยน 2026-10-31 เป็น object วันที่โดยอัตโนมัติ ชนิดจึงเลื่อนไปมาตามภาษา

3. Comment: จุดอ่อนเดียวของ JSON

บทสรุปก่อน: หากมนุษย์ดูแลไฟล์และต้องอธิบายว่าทำไมค่าจึงเป็นเช่นนั้น อย่าใช้ JSON มาตรฐาน

มีเส้นทางปฏิบัติสี่แบบ เรียงตามระดับความรุกราน:

  1. เปลี่ยนไปใช้ JSONC ซึ่งคือ JSON มาตรฐานบวก comment และ trailing comma settings.json และ tsconfig.json ของ VS Code ใช้มัน ต้นทุนคือตัวอ่านต้องใช้ parser ที่เข้าใจ comment เช่น jsonc-parser; JSON.parse ธรรมดาจะล้มเหลว รายละเอียดอยู่ใน JSON5 และ JSONC: JSON ที่มี comment
  2. เก็บเอกสาร sidecar config.json ยังอ่านได้ด้วยเครื่อง ขณะที่ config.md อธิบายว่าฟิลด์แต่ละตัวหมายถึงอะไรและทำไมจึงมีค่านั้น ทั้งสองอยู่ในไดเรกทอรีเดียวกันและเปลี่ยนใน commit เดียวกัน
  3. ใส่คำอธิบายใน schema keyword description และ $comment ของ JSON Schema ใช้บันทึกฟิลด์ได้ แต่ schema ไม่ค่อยถูกส่งไปพร้อม configuration ตอนรัน คนที่อ่าน config จึงอาจไม่เคยเห็นมัน
  4. ย้ายไป TOML หรือ YAML ให้รูปแบบเองมี comment ที่ทุก parser เข้าใจ
{
  // Fixed at 8080: the frontend build script reads this port for its proxy
  "port": 8080,
  // Disable watching to avoid exhausting inodes in CI
  "watch": false
}

JSONC ยังเป็นภาษาถิ่น: นามสกุลยังเป็น .json แต่มีเพียงบางเครื่องมือที่เข้าใจมัน เมื่อข้อมูลออกจากทีมหรือข้ามขอบเขต service เส้นแบ่งระหว่าง JSONC กับ JSON มาตรฐานต้องถูกบันทึกไว้

4. วันที่และ string หลายบรรทัด: บ้านของ TOML

TOML ยกระดับวันที่-เวลาเป็นชนิดชั้นหนึ่งโดยมีสี่แบบ: offset date-time, local date-time, local date และ local time String หลายบรรทัดมีไวยากรณ์เฉพาะที่รักษาการขึ้นบรรทัดใหม่:

title = "json-toolkit"
created = 2026-10-31T09:00:00+08:00
description = """
A JSON toolkit for developers.
Every operation runs locally in the browser.
"""

ข้อมูลเดียวกันใน JSON ต้องลดวันที่ลงเป็น string และ escape การขึ้นบรรทัดใหม่:

{
  "title": "json-toolkit",
  "created": "2026-10-31T09:00:00+08:00",
  "description": "A JSON toolkit for developers.\nEvery operation runs locally in the browser."
}

ใน JSON "created" เป็นเพียง string ที่บังเอิญดูเหมือนวันที่ ข้อมูลชนิดจึงต้องอยู่ในสัญญาฟิลด์: ทั้งสองฝั่งต้องตกลงว่าฟิลด์นี้เป็น RFC 3339 เสมอ TOML ให้ object วันที่จริงกับ parser โดยไม่ต้องมีข้อตกลงด้วยวาจา

YAML ก็เก็บข้อความหลายบรรทัดได้ แต่ block สองสไตล์มีความหมายต่างกัน: | รักษาการขึ้นบรรทัดใหม่ ขณะที่ > พับมันเป็นช่องว่าง เลือกผิดแล้วที่อยู่หรือคำสั่ง SQL จะยุบเป็นบรรทัดเดียว ซึ่งเป็น error ที่จับได้ยากมากในการรีวิว

5. จำนวน: ความแตกต่างที่ถูกละเลยที่สุด

สเปก JSON ไม่จำกัดความแม่นยำของจำนวน แต่ RFC 8259 ยังเตือนว่าความเข้ากันได้ปลอดภัยที่สุดเมื่อถือจำนวนเป็น double ของ IEEE 754 ใน JavaScript จำนวนเต็มที่เกิน 2^53 - 1 สูญเสียความแม่นยำอย่างเงียบ ๆ:

JSON.parse('{"id":9007199254740993}').id
// 9007199254740992: the last digit is gone

TOML กำหนดให้จำนวนเต็ม 64 บิตมีเครื่องหมายถูกจัดการโดยไม่สูญเสีย และให้เกิด error แทนการตัดทิ้งอย่างเงียบ ๆ; float ตาม binary64 และอาจเป็น inf หรือ nan ได้ YAML 1.1 แบกภาระเก่า: 1:30 ถูก parse เป็น 90 (sexagesimal) และ boolean ยอมรับ yes, no, on และ off จึงเกิด "Norway problem" อันโด่งดังที่รหัสประเทศ NO กลายเป็น false

สำหรับเงิน อย่าพึ่ง floating point ในรูปแบบใดเหล่านี้เด็ดขาด: ใช้หน่วยย่อยเป็นจำนวนเต็ม, string หรือชนิด decimal ของฐานข้อมูล การจัดรูปแบบและความแม่นยำมีรายละเอียดเพิ่มเติมใน ขอบเขตของการแปลง JSON, YAML และ XML

6. Table และการซ้อน: ขอบเขตแข็งของ TOML

TOML แสดงการซ้อนด้วย table และ array ของ table:

[server]
port = 8080

[[routes]]
path = "/parse"
method = "POST"

[[routes]]
path = "/minify"
method = "POST"

มีขอบเขตแข็งสองข้อที่ต้องรู้ก่อนแปลง:

  • root ของเอกสาร TOML เป็น table เอกสาร JSON ที่ระดับบนสุดเป็น array (เช่น [1, 2, 3]) จึงไม่มีตัวแทน TOML ที่ถูกกฎหมาย; ต้องห่อเป็น {"items": [...]};
  • TOML ไม่มี null ฟิลด์ null ใน JSON จึงต้องถูกลบหรือแทนที่ด้วย string ว่างหรือค่า sentinel โดยผลักความหมายไปให้ผู้บริโภค

YAML ตรงกันข้าม: ความลึกของการซ้อนไม่จำกัด และ anchor บวก merge key ใช้ชิ้นส่วนซ้ำได้:

defaults: &defaults
  retries: 3
  timeoutMs: 5000

server:
  <<: *defaults
  port: 8080

Anchor เป็นความสามารถเฉพาะ YAML และรับประกันว่าจะสูญเสียระหว่างการแปลง: JSON ไม่มีไวยากรณ์อ้างอิง ไฟล์ที่ขยายแล้วจึงโตขึ้นและไม่มีอะไรบันทึกว่าสองส่วนเคยเป็น configuration เดียวกัน

7. การเลือกตามสถานการณ์

สถานการณ์ คำแนะนำ เหตุผล
API สาธารณะ, message queue, แคช JSON ความเป็นสากลสูงสุด, ต้นทุนการเจรจาเป็นศูนย์
Config ของแอป แบนและมีชนิด TOML Comment, วันที่, จำนวนเต็มไม่สูญเสีย, พฤติกรรม parser เสถียร
Kubernetes, CI, Ansible YAML ระบบนิเวศถูกล็อกไว้; เปลี่ยนรูปแบบคือเปลี่ยนเครื่องมือ
VS Code, tsconfig.json JSONC รองรับโดยธรรมชาติ ไม่ต้องนำรูปแบบใหม่เข้ามา
ใช้ชิ้นส่วน configuration ซ้ำ YAML Anchor และ merge key เป็นตัวเลือกสำเร็จรูปเดียว
สร้างโดยเครื่องและใช้กับเครื่องเท่านั้น JSON (minified) ไม่ต้องมี comment ขนาดและต้นทุน parse ดีที่สุด
โปรเจกต์ Atom หรือ CoffeeScript เดิม CSON แต่วางแผนย้าย ระบบนิเวศชายขอบและต้นทุนการย้ายโตตามเวลา

กฎง่าย ๆ: ให้ระบบนิเวศเลือกไฟล์กำหนดค่า ไม่ใช่ความชอบส่วนตัว เขียน Rust ก็ต้อง Cargo.toml deploy ไป Kubernetes ก็ต้อง YAML สร้างส่วนขยาย VS Code ก็ต้อง JSONC เฉพาะในโปรเจกต์ใหม่ที่ไม่มีข้อจำกัดจากระบบนิเวศ "อันไหนเขียนสนุกกว่า" จึงเป็นคำถามจริง

8. ขอบเขตของการแปลง

ทิศทาง ข้อมูลที่สูญเสียเสมอ คำแนะนำ
JSON → TOML null, array ระดับบนสุด, คีย์ที่แสดงไม่ได้ ปรับโครงสร้างให้เป็นมาตรฐานและตัดฟิลด์ว่างก่อน
TOML → JSON Comment, ชนิดวันที่, inf / nan แปลงวันที่เป็น string RFC 3339
YAML → JSON Comment, anchor และ merge key, tag, หลายเอกสาร ขยาย anchor ก่อน แล้วแปลงทีละเอกสาร
JSON → YAML ไม่สูญเสียโครงสร้าง แต่ string วันที่อาจถูก parse อัตโนมัติ ใส่เครื่องหมายคำพูดให้ string วันที่
CSON → JSON Comment, expression ของ CoffeeScript ย้ายครั้งเดียว อย่าซิงก์สองทาง

เครื่องมือแปลงรับประกันค่า ไม่เคยรับประกัน comment ดังนั้นอย่าออกแบบ pipeline สองทางที่ "JSON เป็นแหล่งและ YAML เป็น build artifact" ให้สร้างทางเดียว หรือดูแลไฟล์แหล่งเดียว

9. รายการตรวจสอบ

  • [ ] บันทึกว่าไฟล์ชนิดไหนใช้รูปแบบไหน และระบุภาษาถิ่นที่อนุญาต;
  • [ ] เลือก TOML หรือ YAML สำหรับ configuration ที่มนุษย์ดูแล และ JSON สำหรับการแลกเปลี่ยนระหว่างเครื่อง;
  • [ ] เก็บวันที่ใน JSON เป็น string RFC 3339 และระบุรูปแบบใน schema;
  • [ ] แทนเงินและจำนวนเต็มที่เกิน 2^53 ด้วย string หรือหน่วยย่อย อย่าใช้ float;
  • [ ] ตรวจแต่ละรูปแบบใน CI ด้วย parser ของมันเอง อย่าใช้ JSON.parse กับ YAML;
  • [ ] ย้ายรูปแบบทางเดียวเท่านั้น และลบไฟล์เก่าเพื่อไม่ให้สองไฟล์เลื่อนออกจากกัน

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

ทำไมการแปลง JSON เป็น TOML จึงล้มเหลวกับบางฟิลด์?

TOML ไม่มี null และ root ของเอกสาร TOML เป็น table ฟิลด์ null ใน JSON จึงต้องถูกลบหรือแทนที่ด้วย string ว่างหรือ sentinel และ array ระดับบนสุดต้องห่อเป็น {"items": [...]} Comment, ชนิดวันที่ และ inf/nan ก็สูญเสียเมื่อไปในทิศทางตรงข้าม ซึ่งเป็นเหตุผลว่าการแปลงควรเป็นทางเดียว

ควรเก็บไฟล์กำหนดค่าสองไฟล์ในรูปแบบต่างกันหรือไม่?

ไม่ เครื่องมือแปลงรับประกันค่าแต่ไม่เคยรับประกัน comment pipeline ที่ "JSON เป็นแหล่งและ YAML เป็น build artifact" จะเลื่อนออกจากกัน ให้สร้างทางเดียว หรือดูแลไฟล์แหล่งเดียวและลบไฟล์เก่าหลังย้าย

จะเพิ่ม comment ให้ไฟล์กำหนดค่า JSON ได้อย่างไร?

JSON มาตรฐานไม่มี comment คุณเปลี่ยนไปใช้ JSONC (ภาษาถิ่นของ VS Code อ่านด้วย jsonc-parser) เก็บเอกสาร sidecar ที่อธิบายแต่ละฟิลด์ หรือย้ายไป TOML หรือ YAML ไฟล์ที่ส่งให้ระบบอื่นควรเป็น JSON มาตรฐาน โดยคำอธิบายอยู่ในเอกสารหรือ schema

TOML หรือ YAML ดีกว่าสำหรับ configuration ของแอป?

เลือก TOML เมื่อโครงสร้างแบน เป็นคู่คีย์-ค่าส่วนใหญ่ และวันที่โดยธรรมชาติสำคัญ; ความหมายคาดเดาได้กว่าและความต่างระหว่าง parser เล็กกว่า เลือก YAML เมื่อต้องซ้อนลึก หลายเอกสาร ใช้ anchor ซ้ำ หรือเมื่อระบบนิเวศเป้าหมายเป็น YAML เป็นหลัก เช่น Kubernetes หรือ CI ทั้งสองรองรับ comment ตัวแยกความแตกต่างจริงจึงคือความซับซ้อนเชิงโครงสร้างและการล็อกกับระบบนิเวศ

ทำไม NO กลายเป็น false ใน YAML?

YAML 1.1 ถือ yes, no, on, off, y และ n เป็น boolean รหัสประเทศ NO ของนอร์เวย์จึงถูก parse เป็น false นี่คือ "Norway problem" หลีกเลี่ยงด้วย implementation ที่ตาม YAML 1.2 หรือใส่เครื่องหมายคำพูดให้ string ทุกตัวที่อาจถูกตีความผิด

CSON ยังคุ้มใช้หรือไม่?

ไม่สำหรับโปรเจกต์ใหม่ CSON พึ่งระบบนิเวศ CoffeeScript มีเครื่องมือที่ได้รับการดูแลน้อย และรองรับใน editor กับ CI จำกัด; หลังจาก Atom หยุดได้รับการดูแล กรณีใช้งานก็หดลงอีก หากโปรเจกต์มี configuration แบบ CSON อยู่แล้ว ให้วางแผนย้ายครั้งเดียวไปยัง JSON, TOML หรือ YAML แทนการเพิ่มมันเข้าไปอีก

แหล่งอ้างอิง

เครื่องมือที่เกี่ยวข้อง

บทความที่เกี่ยวข้อง

ขอบเขตของการแปลง JSON ↔ YAML และ XML

คำกล่าวที่ว่า JSON เป็นซูเปอร์เซตของ YAML รับประกันได้เพียงทิศทางเดียว และ XML ไม่มีมาตรฐานการแมป JSON อย่างเป็นทางการเลย — ทุกอย่างขึ้นอยู่กับข้อตกลง

ระดับกลางอ่านประมาณ 12 นาทีอัปเดต 2026-10-30

JSON5 และ JSONC: JSON ที่มี Comment

ทั้งสองภาษาถิ่นมีอยู่เพราะ config ที่มนุษย์เขียนต้องมี comment และ trailing comma แต่ไวยากรณ์และการเข้าถึงระบบนิเวศต่างกัน เลือกผิด toolchain ก็ติดขัด

ผู้เริ่มต้นอ่านประมาณ 10 นาทีอัปเดต 2026-10-30

JSON หรือ YAML

JSON คั่นโครงสร้างด้วยปีกกา ส่วน YAML ใช้การย่อหน้า: เครื่องจักรได้ JSON คนที่ดูแล config ได้ YAML แต่คอมเมนต์ anchor และโครงสร้างหลายเอกสารจะหายไป

ผู้เริ่มต้นอ่านประมาณ 4 นาทีอัปเดต 2026-10-30