Coding Gun

YAML คืออะไร? และเขียนยังไง?

YAML คือภาษาที่ใช้อธิบายข้อมูล(Serialized Data) เหมือนกับ JSON และ XML ซึ่งออกแบบมาอ่านง่าย โดยใช้โครงสร้างแบบ key-value และการย่อหน้า(indentation) เพื่อกำหนดลำดับชั้นของข้อมูล (nested structure) โดยไม่ต้องใช้วงเล็บเหมือนกับ JSON และ ไม่ต้องมี Tag เปิดปิดเหมือนกับ XML ดังนั้นเราจึงเห็นหลายๆ Platform นำ YAML มาใช้งานยกตัวอย่างเช่น Docker compose, Ansible และ Kubernetes

วิธีการเขียน YAML

ก่อนที่เราจะเขียน YAML เราต้องรู้ข้อกำหนดในการใช้งานก่อน โดยการเขียน YAML จะมีข้อกำหนดต่างๆ ดังนี้

  1. เราสามารถกำหนดนามสกุลเป็น .yaml หรือ .yml ก็ได้
  2. ห้ามใช้ tab ต้องใช้ space เท่านั้น
  3. ถ้าย่อหน้าตรงกันก็จะเป็น Object เดียวกัน
  4. ข้อผิดพลาดส่วนใหญ่เกิดจากการจัด format หรือย่อหน้าที่ไม่ถูกต้อง

หลังจากที่เรารู้ข้อกำหนดต่างๆของ YAML แล้วต่อไปเรามาทำความรู้จักกับ Syntax ของ YAML กัน

Key-Value

ประเภทของข้อมูลที่ใช้มากที่สุดคือ Key และ Value ยกตัวอย่างเช่น

name: John
age: 30

ซึ่งจะตรงกับ JSON ในรูปแบบนี้

{
    "name": "John",
    "age": 30
}

Datatype

YAML จะเลือก Datatype จาก Value ที่เราใส่เข้าไป โดยที่ Datatype จะเป็น

ในกรณีที่เราต้องการกำหนด Datatype ให้กับ Value เลยเราจะใช้เครื่องหมาย !! ตามด้วย Datatype ที่ต้องการยกตัวอย่างเช่น

    year: !!int 2025
    amount: !!float 1000000

Nested Structure

ถ้าต้องการซ้อน Object เราจะใช้ย่อหน้า(indentation) ห้ามใช้ Tab เด็ดขาด เราจึงควรเลือกใช้ Editor ที่ Convert Tab เป็น Space อัตโนมัติ เช่น VSCode

person:
  name: John
  age: 30
  contact:
    email: john@example.com
    phone: 111-111-1111

ซึ่ง YAML ด้านบนจะแปลงเป็น JSON ได้แบบนี้

{
  "person": {
    "name": "John",
    "age": 30,
    "contact": {
      "email": "john@example.com",
      "phone": "111-111-1111"
    }
  }
}

จะเห็นว่า Object contact อยู่ภายใต้ Object Person

List

ถ้าเราต้องการสร้าง List หรือ Array เราจะใช้ - นำหน้าสมาชิกแต่ละตัว ยกตัวอย่างเช่น

skills:
  - Python
  - JavaScript
  - SQL

จะเทียบได้กับ JSON แบบนี้

{
  "skills": [ "Python" , "JavaScript" , "SQL" ]
}

ในกรณีที่เราต้องการ List ของ Objects เราจะใช้ย่อหน้าเฉยๆ ไม่ต้องใส่ - นำหน้า ยกตัวอย่างเช่น

employees:
  - name: John
    role: Developer
  - name: Jenny
    role: Tester

จากตัวอย่างด้่านบนเราจะได้ JSON หน้าตาแบบนี้

{
  "employees": [
    {
      "name": "John",
      "role": "Developer"
    },
    {
      "name": "Jenny",
      "role": "Tester"
    }
  ]
}

Multiline

ถ้าเรามีข้อความที่มีหลายบรรทัดเราสามารถใช้ | เพื่อบอกว่าข้อความในย่อหน้านี้ ทุกๆบรรทัดจะเป็น Value ของ Key เดียวกัน ยกตัวอย่างเช่น

description: |
  This is a multi-line text.
  It will keep line breaks.  

จะเป็นการระบุว่าข้อความทั้ง 2 บรรทัดนี้เป็น Value ของ description แต่ถ้าเราต้องการกำหนดให้ description เป็นข้อความที่ต่อกันไปเรื่อยๆอยู่ในบรรทัดเดียวกัน เราจะใช้เครื่องหมาย >เพื่อข้อความในย่อหน้านี้เป็นบรรทัดเดียว เช่น

summary: >
  This is a long sentence
  that will be folded into
  a single line.  

ผลลัพธ์ของ summary จะเป็น “This is a long sentence that will be folded into a single line.”

Comments

ใน YAML เราจะ comments ด้วยเครื่องหมาย # เหมือนใน Python

# This is a comment
name: Bob  # Inline comment

Anchors และ Aliases

ในกรณีที่เราไม่ต้องการกำหนดค่าซ้ำกันหลายรอบเราจะใช้การอ้างถึงข้อมูลก่อนหน้าด้วย Anchors โดยใช้เครื่องหมาย & และเรียกใช้ด้วย Aliases โดยใช้เครื่องหมาย * ยกตัวอย่างเช่น

server1: &default
  retries: 3
  timeout: 10
  host: server1.local

server2: *default

เปรียบได้กับการเขียน YAML แบบนี้

server1:
  retries: 3
  timeout: 10
  host: server1.local
server2:
  retries: 3
  timeout: 10
  host: server1.local

จากในตัวอย่างนี้จะเห็นว่าชื่อ Host ไม่ถูกต้อง เมื่อเราต้องการ Override หรือแก้ไขค่าเดิมเราจะใช้ << แทนชื่อ Key ยกตัวอย่างเช่น

1
2
3
4
5
6
7
8
server1: &default
  retries: 3
  timeout: 10
  host: server1.local

server2: 
  <<: *default
  host: server2.local

จะเทียบได้กับ YAML หน้าตาแบบนี้

1
2
3
4
5
6
7
8
server1:
  retries: 3
  timeout: 10
  host: server1.local
server2:
  retries: 3
  timeout: 10
  host: server2.local

ซึ่งเราจะเห็นว่าชื่อ Host ของ Server2 ถูกแทนที่ด้วยค่าที่ใส่เข้าไปใหม่(server2.local)

Phanupong Permpimol
Follow me