YAML
2 เครื่องมือ
รูปแบบการอนุกรมข้อมูล
การอนุกรมข้อมูล คือกระบวนการแปลงข้อมูลที่มีโครงสร้างให้อยู่ในรูปแบบที่สามารถจัดเก็บหรือส่งต่อได้ แล้วจึงสร้างใหม่ภายหลัง รูปแบบต่างๆ มีการแลกเปลี่ยนระหว่างความสามารถอ่านได้โดยมนุษย์ ความสามารถในการแยกวิเคราะห์โดยเครื่อง ความสามารถในการแสดงออก และขนาดไฟล์ที่แตกต่างกัน
JSON, YAML, TOML และ XML เป็นสี่รูปแบบการอนุกรมข้อมูลแบบข้อความที่ครองตลาดในการพัฒนาซอฟต์แวร์ แต่ละรูปแบบมีจุดแข็งที่ทำให้เป็นตัวเลือกที่ดีที่สุดในบริบทเฉพาะ — การเข้าใจการแลกเปลี่ยนเหล่านั้นช่วยให้คุณเลือกรูปแบบที่เหมาะสมกับแต่ละงาน
JSON และ YAML เคียงกัน
JSON และ YAML แทนโมเดลข้อมูลเดียวกัน YAML เป็น superset ที่เคร่งครัดของ JSON — เอกสาร JSON ที่ถูกต้องทุกอันก็เป็น YAML ที่ถูกต้องด้วย ด้านล่างเป็นการตั้งค่าเดียวกันที่แสดงในทั้งสองรูปแบบ:
{
"server": {
"host": "localhost",
"port": 8080,
"debug": true
},
"database": {
"url": "postgres://localhost/mydb",
"pool": 10
}
}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 มีความสามารถสูง แต่มีกรณีขอบเขตที่ทำให้นักพัฒนาประหลาดใจอยู่เสมอ ต่อไปนี้คือกรณีที่พบบ่อยที่สุด:
ค่า '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
ข้อกำหนด YAML ห้ามใช้อักขระ tab สำหรับการย่อหน้าโดยชัดเจน editor ที่แปลงช่องว่างเป็น tab โดยอัตโนมัติจะทำให้ไฟล์ YAML ของคุณพังโดยไม่มีการเตือน ควรตั้งค่า editor ให้ใช้ช่องว่างในไฟล์ YAML
YAML มีตัวบ่งชี้ string หลายบรรทัดสองแบบ: | (literal block ซึ่งคงการขึ้นบรรทัดใหม่ไว้) และ > (folded block ซึ่งแปลงการขึ้นบรรทัดใหม่เป็นช่องว่าง) การใช้ผิดประเภทจะให้ผลลัพธ์ที่ไม่ถูกต้องโดยไม่มีข้อผิดพลาด
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 ยาวเป็นบรรทัดเดียว มีประโยชน์สำหรับคำอธิบายยาวๆ
เมื่อต้องการแปลงรูปแบบ
GitHub Actions, GitLab CI และ CircleCI ใช้ YAML โดยตรง เมื่อสร้างคอนฟิก pipeline ด้วยโปรแกรม มักง่ายกว่าที่จะสร้าง JSON object แล้วแปลงเป็น YAML สำหรับผลลัพธ์สุดท้าย
ทรัพยากร Kubernetes ถูกกำหนดใน YAML แต่การสร้าง template ของ Helm chart และเครื่องมือบางอย่างให้ผลลัพธ์เป็น JSON การแปลงระหว่างรูปแบบช่วยให้คุณตรวจสอบ API response และใช้เครื่องมือ JSON มาตรฐาน
REST API ส่งคืน JSON เมื่อนำข้อมูลนั้นไปใช้กับระบบคอนฟิกที่ใช้ YAML (Ansible, Salt, Kubernetes) ตัวแปลงจะเชื่อมช่องว่างโดยไม่ต้องจัดรูปแบบใหม่ด้วยมือ
การย้ายจากเครื่องมือหนึ่งไปยังอีกเครื่องมือหนึ่งมักหมายถึงการแปลงรูปแบบคอนฟิก การแปลงระหว่าง JSON และ YAML ช่วยให้คุณย้ายระหว่าง ecosystem ได้อย่างรวดเร็ว (Node.js → Python, Docker → Kubernetes)
เครื่องมือ JSON Schema มีความสมบูรณ์กว่า YAML Schema รูปแบบที่พบบ่อยคือการเขียนคอนฟิกใน YAML เพื่อความอ่านง่าย แปลงเป็น JSON เพื่อตรวจสอบกับ schema แล้วแปลงกลับสำหรับการ deploy
เครื่องมือภายในอาจใช้คอนฟิก YAML ในขณะที่ API ภายนอกต้องการ JSON ตัวแปลงใน build pipeline ช่วยให้ทั้งสองรูปแบบ sync กันโดยไม่ต้องดูแลไฟล์ซ้ำ
คำถามที่พบบ่อย
ใช่ YAML 1.2 เป็น superset ที่เคร่งครัดของ JSON — เอกสาร JSON ที่ถูกต้องทุกอันก็เป็น YAML ที่ถูกต้องด้วย อย่างไรก็ตาม YAML 1.1 (ที่ยังคงใช้โดย parser หลายตัว) มีกรณีขอบเขตบางอย่างที่ JSON ที่ถูกต้องไม่ใช่ YAML 1.1 ที่ถูกต้อง
YAML รองรับความคิดเห็น ซึ่ง JSON ไม่รองรับ YAML ยังกะทัดรัดกว่าสำหรับโครงสร้างที่ซ้อนกันลึก คุณสมบัติสองอย่างนี้ทำให้เป็นตัวเลือกที่นิยมสำหรับไฟล์คอนฟิกที่แก้ไขโดยมนุษย์ (Docker, Kubernetes, GitHub Actions)
TOML (Tom's Obvious Minimal Language) ถูกออกแบบมาสำหรับไฟล์คอนฟิก มี syntax ที่ชัดเจนคล้าย INI พร้อมประเภทที่ชัดเจนและไม่มีความคลุมเครือ เป็นมาตรฐานสำหรับโปรเจกต์ Rust (Cargo.toml) และ Python (pyproject.toml)
แทบไม่เกิดขึ้น แต่อาจเป็นไปได้ JSON รักษาลำดับ key ใน parser ส่วนใหญ่ (แม้ข้อกำหนดจะระบุว่าไม่มีลำดับ) YAML รองรับ anchor และ tag ที่ไม่มีสิ่งเทียบเท่าใน JSON สำหรับความแม่นยำในการแปลงกลับ ควรใช้เฉพาะ subset ที่เหมือนกัน
JSON.stringify แปลงค่า undefined เป็น null ใน array และละเว้นค่าเหล่านั้นจาก object หากคุณเห็น null ที่ไม่คาดคิดหรือ key ที่หายไปในผลลัพธ์ JSON แสดงว่า object JavaScript ต้นทางน่าจะมี property ที่เป็น undefined
ได้ เนื่องจาก YAML เป็น superset ของ JSON คุณสามารถฝัง JSON syntax โดยตรงภายในเอกสาร YAML ได้ บางครั้งทำเช่นนี้สำหรับโครงสร้างที่ซ้อนกันซับซ้อนที่การย่อหน้าของ YAML อาจสร้างความสับสน