Ana içeriğe geç

JSON Veri Tipleri: String, Number, Boolean, Null, Array, Object

JSON Veri Tipleri: String, Number, Boolean, Null, Array, Object - Veri ve API Rehberi

JSON bir veri taşıma formatıdır ama her değer aynı biçimde taşınmaz. Bir sayı tırnak içinde yazılırsa string olur; bir boolean büyük harfle yazılırsa parse hatası üretir. Bu fark, veriyi üreten tarafta küçük görünür — alıcı tarafta ise sessiz bir uyumsuzluk veya açık bir çökme olarak karşınıza çıkar.

JSON'ın altı veri tipi var: string, number, boolean, null, array ve object. Bunların her birinin syntax kuralları, sınırları ve karıştırıldığı senaryolar farklı.

Altı tipin genel çerçevesi

JSON spesifikasyonu (RFC 8259), primitive tipler (string, number, boolean, null) ile yapısal tipler (array, object) arasında net bir ayrım koyar. Aşağıdaki tablo temel sözdizimini değil, her tipin pratikte ürettiği beklenmedik davranışları gösteriyor:

Tip Örnek Gözden kaçan davranış
string "merhaba" Tek tırnak → geçersiz; 'değer' parse hatası verir
number 42, 3.14, -7 JSON.stringify({x: NaN}){"x":null}, sessizce
boolean true, false "true" string sayılır; === kontrolü başarısız olur
null null undefined serialize edilmez — alan JSON çıktısından silinir
array [1, "a", true] Sondaki virgül (trailing comma) her parser'da hata üretir
object {"anahtar": "deger"} Tırnaksız anahtar → JS'te geçerli, JSON'da geçersiz

Bu altı tipin dışında hiçbir şey JSON'da geçerli değer sayılmaz. Tarih nesnesi, fonksiyon, undefined, sembol — bunların hiçbirinin JSON'da karşılığı yoktur. Varsa serialize adımında dönüştürülmeleri ya da atlanmaları gerekir.

String: tırnak zorunluluğu ve escape karakterleri

JSON'da her string değer çift tırnak içinde yazılmak zorundadır. Tek tırnak, JavaScript'te geçerli bir string gösterimi olsa da JSON spesifikasyonunda yasaktır.

// Geçersiz JSON:
{ 'ad': 'Ali' }

// Geçerli JSON:
{ "ad": "Ali" }

Bir string içinde çift tırnak, ters eğik çizgi veya kontrol karakteri geçiyorsa escape edilmesi gerekir. En sık kullanılanlar:

  • \" — çift tırnak
  • \\ — ters eğik çizgi
  • \n — yeni satır
  • \t — sekme
  • \r — satır başı
  • \uXXXX — Unicode karakter (4 haneli hex)

Gerçek bir yeni satır karakteri tırnak içine doğrudan yazılamaz; \n olarak temsil edilmesi gerekir. Bu kural API yanıtlarında sıklıkla atlanır ve beklenmedik parse hatalarına yol açar.

Türkçe karakterler (ğ, ş, ç, ü, ö, ı, İ) JSON'da doğrudan yazılabilir; UTF-8 ve UTF-16 desteklenir. ISO-8859-1 kullanan eski SOAP servisleri veya Windows-1252 kodlamalı legacy XML API'leriyle entegrasyonda bu karakterler aktarım sırasında bozulabilir. Bu tür senaryolarda \uXXXX Unicode escape kullanmak daha güvenlidir; alıcı taraf kodlamasından bağımsız çalışır.

Number: tek tip, saklı kısıtlar

JSON'da integer ve float ayrımı yoktur. 42, 3.14, -100, 2.5e10 hepsi tek bir number tipiyle temsil edilir. Bu görünür esnekliğin sınırları var.

JSON spesifikasyonu NaN ve Infinity değerlerine izin vermez. JavaScript'te geçerli olan bu sayısal özel değerler JSON dizgesine yazılamaz. JSON.stringify() bu değerlerle karşılaşınca alanı null'a dönüştürür:

JSON.stringify({ deger: NaN })      // '{"deger":null}'
JSON.stringify({ deger: Infinity }) // '{"deger":null}'

Bu sessiz dönüşüm — NaN ve Infinity'nin null'a yazılması — API debug sürecinde saat kayıplarına yol açar. Hata mesajı gelmez; değer kaybolur.

Daha az bilinen bir sorun: büyük integer değerleri. JavaScript'in Number tipi 64-bit float (IEEE 754) kullandığından, 2⁵³'ü (yaklaşık 9 katrilyon) aşan tam sayılar doğru temsil edilemez.

Dikkat: Veritabanı ID'leri veya finansal değerler 2⁵³'ü (9.007.199.254.740.992) aştığında JavaScript sessizce yuvarlar. Veri kaybı hata vermez — yanlış değerle devam eder. Bu tür değerler JSON'da string olarak taşınmalı, alıcı tarafta ise BigInt ile işlenmelidir.
// Sunucu yanıtından büyük ID işleme
const response = { id: "9007199254740993" }  // string olarak taşın
const id = BigInt(response.id)               // alıcı tarafta BigInt'e çevir

Boolean ve null: basit görünen iki tip

Boolean değerler JSON'da yalnızca true ve false olarak yazılır — küçük harfle, tırnaksız. True, TRUE, "true" veya 1 geçerli boolean değerleri değildir.

Bu ayrım pratikte önem taşır. API yanıtında true gelen bir alan boolean, "true" gelen bir alan stringtir. JavaScript'te her ikisi de truthy davranır; sıkı eşitlik kontrolü (===) yapılmadığında uyumsuzluk fark edilmez. Test ortamında sabit değerle çalışan kod, gerçek API'den farklı tip aldığında beklenmedik davranış üretir. Python backend'den gelen True değeri JSON'da true olarak doğru taşınır; sorun genellikle manuel string birleştirme veya template engine çıktılarında ortaya çıkar.

null da aynı biçimde küçük harfle yazılır; bir alanın bilerek boş bırakıldığını gösterir. JavaScript'teki undefined ile aynı değildir: JSON.stringify(), undefined değerli alanları çıktıya dahil etmez; null değerli alanları ise korur.

JSON.stringify({ a: null, b: undefined })
// '{"a":null}'
// b alanı JSON çıktısından silindi

API tüketicisi açısından bu, "alan yok" ile "alan var ama boş" ayrımıdır — genellikle ikisi aynı gibi davranılır; bozulduğunda ise nedeni bulmak zaman alır. null ile undefined farkını bilen bir servis sözleşmesi olmadan bu iki durum birbirinin yerine geçemez.

Array ve Object: kapsayıcı tipler

Array, köşeli parantez içinde virgülle ayrılmış değerlerden oluşur. Elemanlar aynı tipte olmak zorunda değildir: [1, "a", true, null, {"x": 2}] geçerli bir JSON array'idir. Boş array ([]) de geçerlidir.

Object, süslü parantez içinde anahtar-değer çiftlerinden oluşur. Anahtarlar daima çift tırnaklı string olmalıdır — {name: "Ali"} değil, {"name": "Ali"}. JavaScript nesneleri tırnaksız anahtar kabul eder; JSON kabul etmez.

Her iki yapıda da sondaki virgül (trailing comma) yasaktır. Son elemandan veya son anahtar-değer çiftinden sonra virgül bırakmak JSON parser'larını hata ürettirir:

// Geçersiz JSON (trailing comma):
{
  "ad": "Ali",
  "yas": 30,
}

// Geçerli JSON:
{
  "ad": "Ali",
  "yas": 30
}

JavaScript ve bazı modern editörler trailing comma'yı tolere eder. Bu alışkanlık JSON'a taşındığında sessiz uyumsuzluk değil, açık parse hatası üretir — ama sadece JSON'u doğrulayan bir araçta.

Anahtar sırası JSON spesifikasyonunda tanımsızdır; sıraya bağlı mantık uygulama katmanında çözülmelidir.

Tip uyumsuzluğu nerede hata üretir?

Veri tipi sorunları çoğunlukla iki sistemin sınırında ortaya çıkar: API yanıtı okunurken, veritabanından veri çekilirken ya da Go backend'den JavaScript frontend'e payload iletilirken.

Hata üretimde bulunur. Geliştirme ortamında sabit test verisiyle çalışan kod, gerçek API'den farklı tip aldığında sinyalsiz davranış değiştirir.

Örneğin bir boolean alan "true" olarak serialize edilmişse, alıcı taraftaki sıkı kontrol başarısız olur. Ya da sayısal bir ID alanı — veritabanında INTEGER tanımlı, API yanıtına "1234" string olarak eklenmiş. JavaScript'te id === 1234 kontrolü hiçbir zaman eşleşmez; id == 1234 eşleşir. Fark, tip denetiminin ne kadar katı olduğuna göre değişir; sessiz eşleşme hataları bu yüzden üretim ortamına kadar taşınır.

Bu tür sorunları hızlıca yakalamak için yanıtı JSON Formatter'a yapıştırın — string ve number tipler tırnak varlığına göre doğrudan ekranda ayrışır; tip uyumsuzluğu hemen görünür.

JSON Schema doğrulaması kullanan projelerde tip hataları daha erken yakalanır. "type": "number" tanımlı bir alana "42" string değeri geldiğinde doğrulama başarısız olur ve hata üretim ortamına taşınmadan kesilir. JSON syntax kurallarını bilen bir geliştirici için bu doğrulama katmanı basit bir ek adımdır; tip farklarını bilmeyenler için ise defalarca tekrarlanan sessiz hata kaynağı olmaya devam eder.

JSON'ın altı tipi az sayıda kuralla belirlenmiştir. Asıl risk bu kuralların basitliğinden değil, farklı dil ve sistemlerin bu tipleri nasıl yorumladığından kaynaklanır. null ile undefined arasındaki fark, true ile "true" arasındaki fark, büyük integer sınırı — hepsi platforma göre farklı davranış üretebilir. JSON'ın kapsayamadığı binary veriyi base64 string'e dönüştürerek taşırken de hangi tipin kullanılacağı rastgele değil, bilinçli bir karar olmalıdır.