JSON formatı sözdizimi bakımından küçük bir kurallar bütünüdür. Ama bu kurallar katıdır; tek bir virgül fazlası ya da eksik tırnak, parser'ın belgeyi baştan reddetmesine yol açar. Hata mesajı çoğunlukla satır ve sütun numarası verir, ama neden çıktığını anlamak için kuralları baştan bilmek gerekir.
JSON'un iki temel koleksiyonu: object ve array
JSON yalnızca iki veri koleksiyonu tanır: object ve array. Bunların dışına çıkmanın yolu yoktur.
Object, süslü parantez içinde key-value çiftlerinden oluşur. Her key bir string olmak zorundadır; her value ise JSON'un desteklediği herhangi bir veri tipi olabilir:
{
"isim": "Ahmet",
"yas": 32,
"aktif": true
}
Array, köşeli parantez içinde sıralı değerlerin listesidir. Elemanlar aynı tipte olmak zorunda değildir:
[
"SEO",
42,
null,
true
]
Geçerli bir JSON belgesi ya bir object ya da bir array ile başlamalıdır. Teknik olarak tek başına bir string veya sayı da geçerli JSON'dur — ama API response'larında ve yapılandırma dosyalarında pratikte her zaman object ya da array kullanılır.
Key-value çiftleri arasında iki nokta üste üste (:) bulunur. Her çifti virgülle ayırırsınız; son çiftin sonuna virgül gelmez.
String değerlerde çift tırnak zorunlu
JSON'da string değerler yalnızca çift tırnak ile yazılır. Tek tırnak geçersizdir.
// Geçerli
{ "sehir": "Ankara" }
// Geçersiz — tek tırnak
{ 'sehir': 'Ankara' }
Bu kural hem key'ler hem de string value'lar için geçerlidir. JavaScript'te key'i tırnaksız yazmaya alışkınsanız, JSON'a geçişte bu fark sık hataya yol açar:
// JavaScript objesinde geçerli, JSON'da geçersiz
{
isim: "Ahmet",
yas: 32
}
// JSON'da doğru biçim
{
"isim": "Ahmet",
"yas": 32
}
String içinde özel karakterler kullanmak için backslash escape gerekir. JSON şu escape sekanslarını destekler:
\"— çift tırnak\\— backslash\/— eğik çizgi\n— yeni satır\t— tab karakteri\uXXXX— Unicode karakter (örneğinı→ ı)
Backslash karakterini string içinde kullanmak için mutlaka \\ yazmalısınız. Tek \ geçersizdir ve genellikle beklenmedik bir parse hatasına yol açar:
// Geçersiz — backslash escape edilmemiş
{ "yol": "C:\Users\ahmet" }
// Geçerli
{ "yol": "C:\\Users\\ahmet" }
Sayı, boolean ve null: tırnak olmadan yazılan değerler
Tırnak içine aldığınız sayı artık sayı değildir. JSON bu ayrımı tip düzeyinde zorlar: string değerler çift tırnak içinde, sayılar ve boolean'lar tırnaksız yazılır. Bunları karıştırdığınızda tip bilgisi kaybolur — ve bu kayıp çoğunlukla parse aşamasında değil, API tüketicisi matematiksel işlem uygulamaya çalıştığında fark edilir.
{
"fiyat": 149.90,
"stokta": true,
"indirim": null,
"kategori": "elektronik"
}
Burada fiyat gerçek bir sayıdır; "149.90" yazılsaydı string olurdu. API tüketicisi bu değer üzerinde matematiksel işlem yapmayı denediğinde beklenmedik bir hatayla karşılaşırdı.
Boolean değerler yalnızca true ve false olarak yazılır, küçük harfle. True, TRUE veya "true" geçersizdir ya da farklı bir tipe işaret eder. Bu özellikle diğer dillerden gelen geliştiricilerin sık karıştırdığı bir noktadır (Python'da True büyük harfle yazılır; JSON'da parse hatası verir).
JSON'da geçerli sayı formatları:
- Tam sayı:
42,-7,0 - Ondalıklı:
3.14,-0.5 - Üstel gösterim:
1.5e10,2.3E-4
JSON, NaN ve Infinity değerlerini tanımaz. Bu değerleri bir JSON belgesine yazmaya çalışırsanız standart parser'ların büyük çoğunluğu belgeyi reddeder. Sonsuz sayı veya tanımsız sonuçları temsil etmek için genellikle null kullanılır ya da ilgili alan tamamen atlanır.
İç içe yapılar: object içinde array, array içinde object
JSON'un asıl gücü bu iki koleksiyonu birbirine geçirebilmekten gelir. Derinlik sınırı yoktur:
{
"kullanici": {
"id": 101,
"ad": "Zeynep",
"roller": ["admin", "editor"],
"adres": {
"sehir": "İstanbul",
"posta_kodu": "34000"
}
}
}
İç içe yapılarda virgül yerleşimi daha dikkat gerektiren bir hal alır. Her key-value çiftinin sonuna, son eleman dışında, virgül gelir. Aynı kural array elemanları için de geçerlidir. Son elemandan sonra virgül — trailing comma — JSON'da geçersizdir:
// Geçersiz — son elemandan sonra virgül var
{
"renkler": [
"kırmızı",
"mavi",
"yeşil",
]
}
// Geçerli
{
"renkler": [
"kırmızı",
"mavi",
"yeşil"
]
}
JavaScript'te trailing comma çoğunlukla kabul edilir. Bu alışkanlıkla yazılan JSON, her parser'da sorunsuz çalışmaz. 500 satırı geçen bir API response'unda veya iç içe yapılandırma nesnelerinde bu hatayı elle bulmak güçtür; JSON Formatter aracında doğrulama yaparak hem trailing comma hem de diğer syntax hatalarını anında görebilirsiniz.
Whitespace ve biçimlendirme
JSON'da boşluk, sekme ve yeni satır karakterleri value dışında anlamsızdır. Parser bu karakterleri yok sayar. Yani şu iki belge birbirinin tamamen eşdeğeridir:
{"isim":"Ahmet","yas":32}
{
"isim": "Ahmet",
"yas": 32
}
Okunabilirlik için girintili biçim tercih edilir; ağ üzerinden veri aktarımında ise whitespace kaldırılarak dosya küçültülür. Bu işleme minify denir ve JSON boyutunu kayda değer ölçüde azaltabilir. JSON belgelerini whitespace'i kaldırarak küçültmek istiyorsanız minify aracı bu işlemi doğrudan yapar.
Minify ederken satır ve sütun numaraları da kaybolur — parse hatası aldığınızda hata mesajının işaret ettiği konum artık bir anlam taşımaz; belgedeki her şey tek satıra sıkışmıştır. Geliştirme ortamında okunabilir biçimi koruyup production çıktısı için minify uygulamak bu ikisini birbirinden ayırır.
Dikkat: Yalnızca value dışı boşluklar anlamsızdır. String içindeki boşluk ve özel karakterler olduğu gibi korunur. "ad": " Ahmet " yazdıysanız, baştaki ve sondaki boşluklar değerin bir parçasıdır.
JSON'un desteklemediği özellikler ve bunlardan kaynaklanan hatalar
Yorum satırı yok. Undefined yok. Duplicate key kısıtlaması yok. Bu üçü JSON'un tasarım hatası değil, bilerek çizilen sınırıdır — minimal tutulmuş bir serileştirme formatının öngörülebilirlik için ödediği bedeldir.
Yorum satırı yoktur. // veya /* */ ile açıklama ekleyemezsiniz. Bu, yapılandırma dosyalarında sık karşılaşılan bir kısıtlamadır. Yorum gerekiyorsa JSON yerine YAML veya JSONC formatı tercih edilebilir; ancak standart JSON parser'ları bunları reddeder.
Undefined yoktur. JavaScript'in undefined tipi JSON'da karşılık bulmaz. Değeri olmayan bir alan için null kullanılır ya da alan tamamen atlanır. Bu iki seçenek farklı anlam taşır: null değerin bilinçli olarak boş bırakıldığını gösterirken, alanın atlanması o verinin mevcut olmadığını ima eder.
Duplicate key davranışı tanımsızdır. Aynı key'i bir object içinde iki kez yazmak syntax hatası değildir; ama davranış parser'dan parser'a değişir. Bir parser son değeri alabilir, diğeri ilkini — her ikisi de standart dışı olmayan bir davranış sayılır. Bu yüzden aynı key iki kez yazılmamalıdır.
JSON syntax hatalarının büyük çoğunluğu üç kaynaktan gelir: tek tırnak kullanımı, trailing comma ve tırnaksız key. Bu üçü elenince geriye kalan hatalar çok daha az yaygın edge case'lere aittir. Hata mesajlarının nasıl okunduğu ve hangi durumda ne anlama geldiği için JSON parse hatası yazısına bakabilirsiniz.
Syntax kurallarını anlamak, JSON'u elle yazmak için değil — onu üreten sistemin çıktısını okumak ve hata noktasını izole etmek için gereklidir. Servis, kütüphane ya da editor ne üretirse üretsin, doğrulama aracından geçirmek syntax katmanını otomatik hale getirir; ama hangi hatanın neden çıktığını yorumlamak hâlâ bu kurallara hakim olmayı gerektirir.