Tidak suka iklan? Pergi Bebas Iklan Hari ini

YAML vs JSON vs TOML — Format Konfigurasi Mana yang Seharusnya Anda Gunakan?

Diperbarui pada

YAML, JSON, dan TOML semua menyimpan konfigurasi. Mereka tidak dapat saling diganti. YAML akan secara diam-diam mengubah kode negara Anda menjadi nilai boolean. JSON tidak memungkinkan Anda meninggalkan komentar. TOML adalah yang belum pernah digunakan oleh siapa pun di tim Anda. Berikut cara memilih yang tepat.

YAML vs JSON vs TOML — Format Konfigurasi Apa yang Harus Anda Gunakan? 1
IKLAN · HAPUS?

Pada tahun 2015, sebuah playbook Ansible rusak karena baris ini:

country: NO

Konfigurasi yang dimuat tidak menghasilkan kesalahan. Tidak ada keluhan parser. Namun country tidak diatur menjadi string "NO". Ini diatur menjadi false. Karena dalam YAML 1.1, NO adalah nilai boolean. Jadi juga yes, on, off, ydan n. Ini adalah masalah Norwegia, dan telah secara diam-diam mengotori konfigurasi selama bertahun-tahun.

Ini bukan laporan bug YAML. Ini adalah kerangka untuk keputusan yang akan Anda ambil: YAML, JSON, atau TOML untuk konfigurasi berikutnya Anda? Setiap format memiliki keuntungan dan kekurangan nyata, dan jawaban 'hanya gunakan yang digunakan ekosistem' tidak selalu berlaku.

Konfigurasi yang Sama, Tiga Cara

Sebelum kegagalan, berikut konfigurasi aplikasi yang sama ditulis dalam ketiga format:

YAML

# App configuration
app:
  name: my-api
  port: 8080
  debug: false

database:
  host: localhost
  port: 5432
  name: mydb
  pool_size: 10

logging:
  level: info
  format: json
  outputs:
    - stdout
    - /var/log/app.log

JSON

{
  "app": {
    "name": "my-api",
    "port": 8080,
    "debug": false
  },
  "database": {
    "host": "localhost",
    "port": 5432,
    "name": "mydb",
    "pool_size": 10
  },
  "logging": {
    "level": "info",
    "format": "json",
    "outputs": [
      "stdout",
      "/var/log/app.log"
    ]
  }
}

Bahasa Indonesia: TOML

# App configuration
[app]
name = "my-api"
port = 8080
debug = false

[database]
host = "localhost"
port = 5432
name = "mydb"
pool_size = 10

[logging]
level = "info"
format = "json"
outputs = ["stdout", "/var/log/app.log"]

YAML paling kompak tetapi paling berat secara sintaksis. JSON paling rinci tetapi paling eksplisit. TOML berada di tengah: mudah dibaca tanpa konversi tipe implisit dari YAML.

YAML: Kuat, Fleksibel, dan Penuh Dengan Kebocoran

YAML adalah pilihan default untuk pipeline CI/CD (GitHub Actions, GitLab CI, CircleCI), manifest Kubernetes, playbook Ansible, dan kebanyakan alat pengembang. Anda tidak benar-benar memilih YAML — YAML memilih Anda.

Kebocoran yang tercatat:

1. Masalah Boolean (Masalah Norwegia)

YAML 1.1 — spesifikasi yang sebenarnya diimplementasikan oleh sebagian besar parser — menganggap sejumlah besar string sebagai nilai boolean:

# YAML 1.1 boolean values (all parsed as true or false)
enabled: yes      # true
disabled: no      # false  
active: on        # true
paused: off       # false
valid: true       # true
invalid: false    # false

# The Norway Problem in practice:
country_codes:
  NO: Norway      # Key "NO" is fine, but value "NO" becomes false
  SE: Sweden
  YES: Yemen      # "YES" also becomes true

# The fix: quote your strings
country_codes:
  NO: "Norway"
  SE: "Sweden"

YAML 1.2 (diluncurkan pada 2009) memperbaiki ini — hanya true dan false yang merupakan nilai boolean. Masalahnya adalah bahwa PyYAML tidak sepenuhnya menerapkan perilaku 1.2 hingga versi 6.0 pada tahun 2021, dan Go yang populer gopkg.in/yaml.v2 masih menggunakan semantik 1.1 hingga tahun 2024. Jika Anda menggunakan Psych dari Ruby < 4.0 atau PyYAML sebelum versi 6.0, Anda berada di versi 1.1.

2. Tab Akan Mematikan Konfigurasi Anda

YAML melarang karakter tab untuk indentasi. Hanya spasi yang valid. Editor Anda mungkin menampilkan tab dan spasi secara identik, file mungkin terlihat benar, namun YAML tetap akan menampilkan:

yaml.scanner.ScannerError: while scanning a block mapping
  found character '\t' that cannot start any token

Ini adalah kesalahan yang membuat pengembang pemula mempertanyakan pilihan karier mereka. Konfigurasikan editor Anda agar tab diubah menjadi spasi dalam file YAML. Setiap editor mendukung ini; tidak semua editor memiliki fitur ini secara default.

3. String Multiline Tidak Jelas

# | (literal block): preserves newlines exactly
description: |
  Line one.
  Line two.
  Line three.
# Result: "Line one.\nLine two.\nLine three.\n"

# > (folded block): folds newlines into spaces
short_desc: >
  This will all become
  one long line.
# Result: "This will all become one long line.\n"

# Trailing newlines: | adds one, |+ adds all, |- strips them all
desc_stripped: |-
  No trailing newline.

Tidak ada yang menghafal ini tanpa mencari referensi. Mnemonik yang saya gunakan: | terlihat seperti baris baru, > terlihat seperti sesuatu yang ditekan bersama. Ini masih membingungkan hingga tiga tahun lebih lanjut.

Kapan YAML Menang

  • Anda menulis manifest Kubernetes, workflow GitHub Actions, atau playbook Ansible — Anda tidak memiliki pilihan.
  • Konfigurasi Anda memiliki banyak komentar yang menjelaskan nilai-nilai yang tidak jelas. YAML mendukung komentar inline; JSON dan TOML juga mendukungnya, tetapi YAML paling alami untuk konfigurasi yang kaya komentar.
  • Data Anda memiliki struktur yang sangat terdalam yang akan terlihat buruk jika digunakan dalam tabel datar TOML.
  • Tim Anda sudah terbiasa dan memiliki linter (yamllint) dalam pipeline.

JSON: Pekerjaan yang Monoton, Tahan Banting

JSON dirancang sebagai format pertukaran data, bukan format konfigurasi. Douglas Crockford secara sengaja menghilangkan komentar — argumennya adalah bahwa komentar akan digunakan untuk direktif yang akan berbeda antar parser. Ini adalah alasan mengapa package.json tidak memiliki komentar dan tsconfig.json secara teknis adalah JSON dengan komentar (JSONC), yang merupakan hal yang terpisah dan tidak didukung oleh sebagian besar parser JSON.

Masalah nyata JSON untuk file konfigurasi:

  • Tidak ada komentar. Anda tidak bisa menjelaskan mengapa "maxRetries": 3 dan bukan 5. Anda tidak bisa menambahkan TODO. Anda tidak bisa menandai field sebagai dihapus. Ini benar-benar menyakitkan untuk file konfigurasi yang bertahan lebih dari penulisnya.
  • Tidak ada koma di akhir. Menambahkan item ke dalam array berarti mengubah baris sebelumnya untuk menambahkan koma. Setiap perubahan JSON menjadi perubahan dua baris. Setiap konflik penggabungan menjadi lebih buruk daripada yang perlu.
  • Terlalu rinci untuk data yang terdalam. Enam baris kurung dan tanda kurung untuk apa yang YAML lakukan dalam tiga baris indentasi.
  • Semua angka memiliki tipe yang sama. JSON tidak membedakan antara bilangan bulat dan desimal. 1 dan 1.0 keduanya hanya merupakan angka, dan tipe yang dihasilkan oleh bahasa Anda tergantung pada parser.

Namun keandalan JSON juga merupakan fitur utamanya. Setiap bahasa memiliki parser JSON. Spesifikasi tidak ambigu. Tidak ada konversi tipe implisit. Sebuah string selalu merupakan string — "yes" tidak akan secara diam-diam menjadi true. Jika Anda perlu memvalidasi konfigurasi JSON secara programatis, IO Tools’ JSON Formatter dapat menangkap kesalahan sintaks sebelum mencapai produksi — berguna ketika seseorang mengedit konfigurasi secara manual dan lupa menambahkan koma di akhir.

Kapan JSON Menang

  • Respons API atau konfigurasi yang dikonsumsi oleh berbagai bahasa/layanan. JSON bersifat universal; dukungan TOML kurang sempurna di beberapa ekosistem.
  • Anda membutuhkan jaminan tipe yang ketat. Validasi skema JSON sudah matang, didukung secara luas, dan banyak digunakan (VS Code menggunakan ini untuk autocomplete pengaturan).
  • Konfigurasi ini dihasilkan secara mesin. Tidak ada yang menulis JSON secara manual jika mereka bisa menghindarinya — tetapi mesin menghasilkannya dengan baik.
  • Anda bekerja di Node.js atau JavaScript di depan, di mana JSON adalah warga asli.

TOML: Konfigurasi yang Dibuat dengan Pendekatan yang Tepat

TOML (Tom’s Obvious, Minimal Language) diciptakan oleh Tom Preston-Werner, pendiri GitHub, khususnya untuk file konfigurasi. TOML mencapai versi 1.0 pada Januari 2021. Ini adalah format default untuk Rust’s Cargo.toml, Python’s pyproject.toml, dan situs statis Hugo.

Filosofi desain TOML: tipe harus eksplisit, struktur harus datar sejauh mungkin, dan harus ada tepat satu cara yang jelas untuk menulis nilai konfigurasi apa pun.

# Types are unambiguous in TOML
name = "my-app"          # string: always quoted
port = 8080              # integer
threshold = 3.14         # float
enabled = true           # boolean: only true/false, no yes/no
created = 2024-01-15     # date: native type
tags = ["api", "prod"]   # array

# "yes" is just a string. Always.
country = "NO"           # string "NO", no boolean nonsense

Kekurangan kasar:

  • Sintaks array dari tabel benar-benar tidak nyaman. [[products]] dan [products.details] terlihat mirip tetapi berperilaku secara berbeda. Spesifikasi masuk akal; perbedaan visual tidak.
  • Penggabungan yang dalam menjadi panjang. Apa yang dilakukan YAML dalam 5 baris indentasi, TOML melakukannya dalam 3 header bagian terpisah. Untuk konfigurasi lebih dari 3 level, TOML mulai terasa seperti alat yang salah.
  • Ketersediaan parser. Parser TOML tersedia untuk setiap bahasa utama, tetapi mereka bervariasi dalam kepatuhan terhadap spesifikasi. Uji coba kepatuhan TOML sering mengungkapkan kasus ujung. Parser JSON telah diuji secara jauh lebih banyak penggunaan. Kebiasaan tim.
  • Jika Anda menggunakan TOML di luar ekosistem Rust atau Python, harapkan setidaknya satu anggota tim akan membuka PR dengan pertanyaan “apa format ini?” Jika Anda menggunakan TOML di luar ekosistem Rust atau Python, harap siapkan setidaknya satu rekan untuk membuka PR dengan pertanyaan "apa format ini?"

Kapan TOML Menang

  • Proyek Rust — Cargo.toml adalah standar dan alatnya sangat baik.
  • Proyek Python yang menggunakan pyproject.toml (PEP 518) — ini sekarang adalah tempat rekomendasi untuk konfigurasi alat seperti Black, Ruff, mypy, dan pytest.
  • Konfigurasi sederhana dan datar di mana kepekaan indentasi YAML akan menjadi kekurangan.
  • Anda ingin dukungan waktu dan tanggal tanpa mengubahnya menjadi string.

Panduan Keputusan Cepat

  • Kubernetes / pipeline CI/CD / playbook Ansible? YAML. Tidak ada pilihan.
  • Konfigurasi API yang dikonsumsi oleh berbagai layanan dalam bahasa yang berbeda? JSON.
  • Proyek Rust? TOML (konvensi Cargo.toml).
  • Konfigurasi proyek Python (linters, formatters, alat pembangunan)? TOML (pyproject.toml adalah standar sekarang).
  • Konfigurasi situs statis (Hugo, Zola)? TOML, meskipun umumnya mendukung ketiga format tersebut.
  • Konfigurasi proyek Node.js? JSON (ekosistem package.json), atau YAML jika Anda membutuhkan komentar.
  • Orang-orang akan sering mengedit ini dan membutuhkan catatan? YAML atau TOML (keduanya mendukung komentar). Tidak JSON.
  • Anda ingin keamanan tipe yang ketat dan validasi skema? JSON + Validasi Skema JSON.

Jawaban yang jujur untuk kebanyakan proyek baru: gunakan format yang diharapkan oleh ekosistem bahasa utama. Rust mengharapkan TOML. Alat Python mengharapkan TOML atau YAML. Node.js mengharapkan JSON. Jika Anda menulis sesuatu yang tidak tergantung pada bahasa, pemisahan yang wajar adalah TOML untuk konfigurasi yang diedit manusia dan JSON untuk konfigurasi yang dihasilkan dan dikonsumsi oleh mesin.

Ingin bebas iklan? Bebas Iklan Hari Ini

Instal Ekstensi Kami

Tambahkan alat IO ke browser favorit Anda untuk akses instan dan pencarian lebih cepat

Ke Ekstensi Chrome Ke Ekstensi Tepi Ke Ekstensi Firefox Ke Ekstensi Opera

Papan Skor Telah Tiba!

Papan Skor adalah cara yang menyenangkan untuk melacak permainan Anda, semua data disimpan di browser Anda. Lebih banyak fitur akan segera hadir!

IKLAN · HAPUS?
IKLAN · HAPUS?
IKLAN · HAPUS?

Pojok Berita dengan Sorotan Teknologi

Terlibat

Bantu kami untuk terus menyediakan alat gratis yang berharga

Belikan aku kopi
IKLAN · HAPUS?