ToolDeck

YAML

2 เครื่องมือ

รูปแบบการอนุกรมข้อมูล

การอนุกรมข้อมูล คือกระบวนการแปลงข้อมูลที่มีโครงสร้างให้อยู่ในรูปแบบที่สามารถจัดเก็บหรือส่งต่อได้ แล้วจึงสร้างใหม่ภายหลัง รูปแบบต่างๆ มีการแลกเปลี่ยนระหว่างความสามารถอ่านได้โดยมนุษย์ ความสามารถในการแยกวิเคราะห์โดยเครื่อง ความสามารถในการแสดงออก และขนาดไฟล์ที่แตกต่างกัน

JSON, YAML, TOML และ XML เป็นสี่รูปแบบการอนุกรมข้อมูลแบบข้อความที่ครองตลาดในการพัฒนาซอฟต์แวร์ แต่ละรูปแบบมีจุดแข็งที่ทำให้เป็นตัวเลือกที่ดีที่สุดในบริบทเฉพาะ — การเข้าใจการแลกเปลี่ยนเหล่านั้นช่วยให้คุณเลือกรูปแบบที่เหมาะสมกับแต่ละงาน

JSON และ YAML เคียงกัน

JSON และ YAML แทนโมเดลข้อมูลเดียวกัน YAML เป็น superset ที่เคร่งครัดของ JSON — เอกสาร JSON ที่ถูกต้องทุกอันก็เป็น YAML ที่ถูกต้องด้วย ด้านล่างเป็นการตั้งค่าเดียวกันที่แสดงในทั้งสองรูปแบบ:

JSON
{
  "server": {
    "host": "localhost",
    "port": 8080,
    "debug": true
  },
  "database": {
    "url": "postgres://localhost/mydb",
    "pool": 10
  }
}
YAML
server:
  host: localhost
  port: 8080
  debug: true
database:
  url: postgres://localhost/mydb
  pool: 10

YAML ใช้การย่อหน้าแทนวงเล็บปีกกาและวงเล็บเหลี่ยม และละเว้นเครื่องหมายอัญประกาศจากค่า string ส่วนใหญ่ ทำให้กะทัดรัดและอ่านง่ายขึ้นสำหรับไฟล์ที่แก้ไขโดยมนุษย์ แต่ก็มีความอ่อนไหวต่อการย่อหน้าด้วย

เปรียบเทียบรูปแบบ

รูปแบบอ่านง่ายความคิดเห็นอาร์เรย์เหมาะสำหรับ
JSON★★★☆☆ไม่รองรับความคิดเห็นรองรับโดยตรงAPI, การแลกเปลี่ยนข้อมูล
YAML★★★★★ใช่ (#)รองรับโดยตรงไฟล์คอนฟิก, IaC
TOML★★★★☆ใช่ (#)รองรับโดยตรงคอนฟิกแอป (Rust, Python)
XML★★☆☆☆ใช่ (<!-- -->)องค์ประกอบซ้ำเอกสาร, SOAP, SVG

ข้อควรระวังใน YAML

YAML มีความสามารถสูง แต่มีกรณีขอบเขตที่ทำให้นักพัฒนาประหลาดใจอยู่เสมอ ต่อไปนี้คือกรณีที่พบบ่อยที่สุด:

ปัญหา Norway

ค่า 'NO' ที่ไม่มีเครื่องหมายอัญประกาศจะถูกตีความเป็น boolean false ใน YAML 1.1 รหัสประเทศอย่าง NO (นอร์เวย์), OFF, FALSE, N ล้วนถูกแยกวิเคราะห์เป็น false ใน YAML 1.2 ปัญหานี้ได้รับการแก้ไขแล้ว แต่ parser หลายตัวยังใช้กฎของ 1.1 อยู่ ควรใส่เครื่องหมายอัญประกาศกับ string ที่อาจมีความคลุมเครือเสมอ

ความอ่อนไหวต่อการย่อหน้า

YAML ใช้การย่อหน้าเพื่อกำหนดโครงสร้าง ช่องว่างพิเศษหนึ่งช่องหรืออักขระ tab สามารถเปลี่ยนความหมายของเอกสารได้อย่างสิ้นเชิง Tab ถูกห้ามใช้เป็นการย่อหน้าใน YAML — ใช้ได้เฉพาะช่องว่างเท่านั้น

การแปลงประเภทอัตโนมัติ

ค่าที่ไม่มีเครื่องหมายอัญประกาศซึ่งดูเหมือนตัวเลข boolean หรือ null จะถูกแปลงโดยอัตโนมัติ '1.0' จะกลายเป็น float, '2024-01-01' จะกลายเป็น object วันที่ใน parser บางตัว ควรใส่เครื่องหมายอัญประกาศกับค่าที่ต้องการเก็บเป็น string

Tab ถูกห้าม

ข้อกำหนด YAML ห้ามใช้อักขระ tab สำหรับการย่อหน้าโดยชัดเจน editor ที่แปลงช่องว่างเป็น tab โดยอัตโนมัติจะทำให้ไฟล์ YAML ของคุณพังโดยไม่มีการเตือน ควรตั้งค่า editor ให้ใช้ช่องว่างในไฟล์ YAML

โหมด string หลายบรรทัด

YAML มีตัวบ่งชี้ string หลายบรรทัดสองแบบ: | (literal block ซึ่งคงการขึ้นบรรทัดใหม่ไว้) และ > (folded block ซึ่งแปลงการขึ้นบรรทัดใหม่เป็นช่องว่าง) การใช้ผิดประเภทจะให้ผลลัพธ์ที่ไม่ถูกต้องโดยไม่มีข้อผิดพลาด

การวนซ้ำใน Anchor และ Alias

YAML anchor (&) และ alias (*) ช่วยให้นำ node กลับมาใช้ใหม่ได้ ซึ่งมีประสิทธิภาพสูง แต่อาจสร้างการอ้างอิงแบบวงกลมที่ทำให้เกิด infinite loop หรือ memory หมดใน parser ที่ไม่ได้รับการป้องกัน ควรตรวจสอบ YAML ที่ใช้ anchor จากแหล่งที่ไม่น่าเชื่อถือ

คุณสมบัติเฉพาะของ YAML

ความคิดเห็น

YAML รองรับความคิดเห็นด้วยอักขระ # ซึ่งเป็นข้อได้เปรียบในทางปฏิบัติที่สำคัญที่สุดเมื่อเทียบกับ JSON สำหรับไฟล์คอนฟิก — คุณสามารถบันทึกการตั้งค่าของคุณแบบ inline ได้ ความคิดเห็นสามารถปรากฏในบรรทัดของตัวเองหรือหลังค่า

Anchor และ Alias

YAML ให้คุณกำหนด node ครั้งเดียวด้วย &anchor-name และนำกลับมาใช้ที่ใดก็ได้ด้วย *anchor-name ซึ่งช่วยลดการซ้ำในคอนฟิกที่ซับซ้อน Kubernetes และ Docker Compose ใช้ anchor อย่างแพร่หลายสำหรับนิยาม service ที่ใช้ร่วมกัน

String หลายบรรทัด

YAML รองรับ block scalar สองโหมด: literal block (|) คงการขึ้นบรรทัดใหม่ตามที่เขียน มีประโยชน์สำหรับ script และ template ส่วน folded block (>) รวม string ยาวเป็นบรรทัดเดียว มีประโยชน์สำหรับคำอธิบายยาวๆ

เมื่อต้องการแปลงรูปแบบ

การตั้งค่า CI/CD pipeline

GitHub Actions, GitLab CI และ CircleCI ใช้ YAML โดยตรง เมื่อสร้างคอนฟิก pipeline ด้วยโปรแกรม มักง่ายกว่าที่จะสร้าง JSON object แล้วแปลงเป็น YAML สำหรับผลลัพธ์สุดท้าย

แมนิเฟสต์ Kubernetes

ทรัพยากร Kubernetes ถูกกำหนดใน YAML แต่การสร้าง template ของ Helm chart และเครื่องมือบางอย่างให้ผลลัพธ์เป็น JSON การแปลงระหว่างรูปแบบช่วยให้คุณตรวจสอบ API response และใช้เครื่องมือ JSON มาตรฐาน

การประมวลผล API response

REST API ส่งคืน JSON เมื่อนำข้อมูลนั้นไปใช้กับระบบคอนฟิกที่ใช้ YAML (Ansible, Salt, Kubernetes) ตัวแปลงจะเชื่อมช่องว่างโดยไม่ต้องจัดรูปแบบใหม่ด้วยมือ

การย้ายรูปแบบคอนฟิก

การย้ายจากเครื่องมือหนึ่งไปยังอีกเครื่องมือหนึ่งมักหมายถึงการแปลงรูปแบบคอนฟิก การแปลงระหว่าง JSON และ YAML ช่วยให้คุณย้ายระหว่าง ecosystem ได้อย่างรวดเร็ว (Node.js → Python, Docker → Kubernetes)

ขั้นตอนการตรวจสอบ Schema

เครื่องมือ JSON Schema มีความสมบูรณ์กว่า YAML Schema รูปแบบที่พบบ่อยคือการเขียนคอนฟิกใน YAML เพื่อความอ่านง่าย แปลงเป็น JSON เพื่อตรวจสอบกับ schema แล้วแปลงกลับสำหรับการ deploy

การแลกเปลี่ยนข้อมูลกับ API

เครื่องมือภายในอาจใช้คอนฟิก YAML ในขณะที่ API ภายนอกต้องการ JSON ตัวแปลงใน build pipeline ช่วยให้ทั้งสองรูปแบบ sync กันโดยไม่ต้องดูแลไฟล์ซ้ำ

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

YAML เป็น superset ของ JSON หรือไม่?

ใช่ YAML 1.2 เป็น superset ที่เคร่งครัดของ JSON — เอกสาร JSON ที่ถูกต้องทุกอันก็เป็น YAML ที่ถูกต้องด้วย อย่างไรก็ตาม YAML 1.1 (ที่ยังคงใช้โดย parser หลายตัว) มีกรณีขอบเขตบางอย่างที่ JSON ที่ถูกต้องไม่ใช่ YAML 1.1 ที่ถูกต้อง

ทำไมถึงควรเลือก YAML แทน JSON สำหรับไฟล์คอนฟิก?

YAML รองรับความคิดเห็น ซึ่ง JSON ไม่รองรับ YAML ยังกะทัดรัดกว่าสำหรับโครงสร้างที่ซ้อนกันลึก คุณสมบัติสองอย่างนี้ทำให้เป็นตัวเลือกที่นิยมสำหรับไฟล์คอนฟิกที่แก้ไขโดยมนุษย์ (Docker, Kubernetes, GitHub Actions)

TOML คืออะไร และควรใช้เมื่อใด?

TOML (Tom's Obvious Minimal Language) ถูกออกแบบมาสำหรับไฟล์คอนฟิก มี syntax ที่ชัดเจนคล้าย INI พร้อมประเภทที่ชัดเจนและไม่มีความคลุมเครือ เป็นมาตรฐานสำหรับโปรเจกต์ Rust (Cargo.toml) และ Python (pyproject.toml)

การแปลง JSON เป็น YAML อาจสูญเสียข้อมูลได้หรือไม่?

แทบไม่เกิดขึ้น แต่อาจเป็นไปได้ JSON รักษาลำดับ key ใน parser ส่วนใหญ่ (แม้ข้อกำหนดจะระบุว่าไม่มีลำดับ) YAML รองรับ anchor และ tag ที่ไม่มีสิ่งเทียบเท่าใน JSON สำหรับความแม่นยำในการแปลงกลับ ควรใช้เฉพาะ subset ที่เหมือนกัน

อะไรทำให้ 'undefined' ปรากฏในผลลัพธ์ JSON?

JSON.stringify แปลงค่า undefined เป็น null ใน array และละเว้นค่าเหล่านั้นจาก object หากคุณเห็น null ที่ไม่คาดคิดหรือ key ที่หายไปในผลลัพธ์ JSON แสดงว่า object JavaScript ต้นทางน่าจะมี property ที่เป็น undefined

สามารถใช้ JSON ในไฟล์ YAML ได้หรือไม่?

ได้ เนื่องจาก YAML เป็น superset ของ JSON คุณสามารถฝัง JSON syntax โดยตรงภายในเอกสาร YAML ได้ บางครั้งทำเช่นนี้สำหรับโครงสร้างที่ซ้อนกันซับซ้อนที่การย่อหน้าของ YAML อาจสร้างความสับสน