Ana içeriğe geç

JSON Schema Nedir? Veri Yapısı Doğrulama

JSON Schema Nedir? Veri Yapısı Doğrulama - Veri ve API Rehberi

Bir API uç noktası beklenmedik bir alanla yanıt verdiğinde ya da zorunlu bir alan eksik geldiğinde, hata çoğunlukla çalışma zamanında patlar; geliştirme aşamasında değil. JSON Schema, bu sorunu veri yapısına dair beklentileri makine tarafından okunabilir bir sözleşmeye dönüştürerek çözer. Sözleşmeyi kim ihlal ettiği, ne zaman ihlal ettiği ve hangi alan üzerinde ihlal ettiği, doğrulama motorundan gelen hata çıktısında açıkça görünür.

JSON Schema'nın Anatomisi

JSON Schema, bir JSON belgesinin geçerli sayılabilmesi için hangi koşulları sağlaması gerektiğini tanımlayan, yine JSON formatında yazılmış bir şemadır. Şemanın kendisi de JSON olduğu için ayrı bir söz dizimi öğrenilmez; yalnızca hangi keyword'ün ne anlama geldiği öğrenilir.

Temel yapı dört keyword üzerine kuruludur. $schema alanı hangi draft versiyonunun kullanıldığını bildirir; bu alan doğrulama davranışını doğrudan etkiler çünkü draft 2019-09 ile draft 7 arasında birkaç keyword'ün yorumlanma biçimi farklıdır. type alanı değerin veri tipini kısıtlar: "string", "number", "integer", "boolean", "array", "object" veya "null". properties, nesne türündeki bir belgenin hangi alanlara sahip olduğunu ve her alanın nasıl doğrulanacağını tanımlar. required ise bu alanlardan hangilerinin zorunlu olduğunu dizi biçiminde listeler.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "kullanici_id": { "type": "integer" },
    "eposta": { "type": "string", "format": "email" },
    "aktif": { "type": "boolean" }
  },
  "required": ["kullanici_id", "eposta"]
}

Bu şemada aktif alanı required listesinde yer almadığından opsiyoneldir; belge bu alan olmadan da geçerli sayılır. kullanici_id veya eposta eksik bir belge validasyondan geçemez. format: "email" keyword'ü ise bir ipucu tanımlayıcıdır (doğrulama garantisi veren bir kısıtlama değil); bazı doğrulama kütüphaneleri onu zorunlu olarak kontrol ederken bazıları görmezden gelir, bu nedenle format doğrulamasının aktif olup olmadığı kullanılan kütüphaneye bağlıdır.

Doğrulama Motorunun Gerçekte Ne Yaptığı

Bir validator belgeyi şemayla karşılaştırırken keyword'leri belirli bir değerlendirme sırasında işler. Önce root seviyesindeki type kontrolü gelir; değer nesne değilse tüm diğer kontroller atlanır. Ardından required listesindeki her anahtarın belgede bulunup bulunmadığı kontrol edilir. Sonra properties altındaki her alanın kendi alt şemasına uygunluğu değerlendirilir.

additionalProperties keyword'ü varsayılan olarak true'dur; yani şemada tanımlanmamış alanların belgede bulunması geçerli sayılır. Bu davranışı değiştirmek için "additionalProperties": false yazılır. additionalProperties: false kırılgan kontrat demektir. API'nin genişlemesi sırasında, yani karşı tarafın kontrolünüzün dışında yeni bir alan eklediği durumlarda, mevcut şema bu alanı tanımadığı için her geçerli yanıtı reddeder; bu sessiz bir uyarı değil açık bir doğrulama hatası olarak geri döner ve entegrasyonu kırar.

allOf, anyOf ve oneOf birleştirme keyword'leri yapısal olarak farklı davranır. allOf içindeki tüm alt şemaların koşulları aynı anda sağlanmalıdır; bu, paylaşılan taban şemayı genişletmek için kullanılır. anyOf listesindeki en az bir alt şema geçerliyse belge kabul edilir; bu da performans açısından en esnek olandır. oneOf ise yalnızca bir alt şemanın eşleşmesini bekler; birden fazla eşleşme durumunda doğrulama başarısız sayılır. Üçü teoride net; validator loglarında oneOf başarısızlığını yorumlamak bambaşka bir iştir. Bu ayrım yanlış anlaşıldığında, belge validator'dan geçer ama iş mantığı beklenen koldan ilerlemez.

Hata okuma ve yanlış yorumlama tuzakları

Yalnızca hata mesajının metnine bakılarak kök neden bulunamaz. JSON Schema validator'ları hata çıktısını JSON Pointer söz diziminde raporlar: /kullanici_id gibi bir pointer, hatanın hangi alana ait olduğunu gösterir. Kök seviyesindeki hata / ile işaretlenir; iç içe nesnelerde ise /siparis/kalemler/0/miktar gibi tam bir yol belirtilir.

Bir alanda required ve type hatası aynı anda çıkabilir. Bu durum, zorunlu bir alan eksikse ve aynı zamanda şema o alan için tip kısıtlaması tanımlamışsa ortaya çıkar. Validator önce zorunluluğu raporlar; ancak alan ileride eklenirse tip hatası da görünür hale gelir. Yalnızca ilk hata mesajını düzeltip kalan hataları sonraya bırakmak, test döngüsünü gereksiz yere uzatır.

Sayısal tip ayrımı da sık karıştırılan bir hata modudur. "type": "integer" ile "type": "number" aynı değildir. 42 her ikisini de karşılar; ama 42.5 yalnızca number tipiyle geçerlidir. API'nin ondalık değer döndürdüğü bir alanı integer olarak tanımlamak, geçerli bir verinin reddedilmesine neden olur. Bu hata özellikle fiyat veya oran alanlarında, verinin format değişikliğinin şemaya yansıtılmadığı durumlarda çıkar.

Minimum ve maksimum kısıtlamaları nümerik tipler için söz dizimsel olarak açıktır ama string uzunlukları için minLength ve maxLength farklı keyword'lerdir. minimum: 1 bir string alanına uygulanamaz; validator bunu sessizce geçebilir ya da kütüphaneye bağlı olarak uyarı verebilir.

Schema tasarımında trade-off'lar

Aşırı kısıtlayıcı bir şema geçerli verileri reddeder. Aşırı gevşek bir şema ise bozuk veriyi kabul eder. Bu iki uç arasındaki denge, şemanın hangi riski öncelediğiyle belirlenir: entegrasyon kırılması mı, yoksa veri bütünlüğü mi?

Şema bakım maliyeti, tanımlanan alanların sayısıyla değil katılık derecesiyle artar. Her eklenen additionalProperties: false, API versiyonları arasındaki her küçük değişiklikte şemanın manuel olarak güncellenmesini zorunlu kılar. Büyük ekiplerde ya da üçüncü taraf API'lerle çalışırken bu yük hızla birikiyor. Kural gevşetildi; hata kayboldu; ama veri bozuk. Şemayı yeterince kısıtlamamak, validasyonun geçmesini sağlar ama yanlış veriyle devam eden iş akışının daha sonra çok daha zorlu bir noktada patlamasına zemin hazırlar.

Pratik bir orta yol olarak zorunlu alanlar ve kritik tip kısıtlamaları katı tutulurken, opsiyonel genişleme alanları için additionalProperties varsayılan davranışa bırakılır. Bu yaklaşım API'nin büyümesine karşı dirençli bir şema sağlar ve yalnızca iş mantığının doğrudan bağlı olduğu alanlar üzerinde sıkı kontrol uygular.

Dizi tipindeki alanlar için items keyword'ü her elemanın şemasını tanımlar. Dizi boş olabilir mi sorusu çoğunlukla atlanır; minItems: 1 eklenmediği sürece boş dizi geçerli sayılır. Bir sipariş sistemi düşünüldüğünde, sıfır kalem içeren bir siparis nesnesinin validasyondan geçmesi iş mantığında ciddi bir açıktır.

API payload'ları üretim ortamına geçerken çoğunlukla sıkıştırılmış formatta iletilir: gereksiz boşluklar ve satır sonları çıkarılır, boyut küçülür. Geliştirme aşamasında şemayı test ederken ise yapının okunabilir olması hata ayıklamayı kolaylaştırır. Sıkıştırılmış bir JSON dosyasını doğrulama öncesinde okunabilir hale getirmek için bir araçtan yararlanmak, özellikle derinlemesine iç içe geçmiş nesnelerde JSON Pointer'ın hangi alana işaret ettiğini takip etmeyi kolaylaştırır; hata ayıklamada yapıyı gözle izlemek, sıkıştırılmış tek satır üzerinde bunu yapmaktan çok daha az hata üretir.

Pratik doğrulama akışı ve araç desteği

JSON Schema doğrulaması bir kez yazılıp unutulan bir yapılandırma değildir. API versiyonları değiştikçe, veri modeli genişledikçe şema da güncellenir. Bu nedenle şemayı test edebileceğiniz bir doğrulama aracı, geliştirme akışının içinde kalmalıdır.

Şema yazılırken söz dizimsel hataları bulmak, formatı düzenlemek ve belgeyi okunabilir hale getirmek için JSON yapısını ayrıştırıp söz dizimini doğrulayan bir araçtan yararlanabilirsiniz. Araç JSON yapısını ayrıştırır, girintileri düzenler ve geçersiz söz dizimini anında işaretler; büyük bir şema dosyasını elle izlemek yerine bu doğrulama adımını kaynakta kesmek zaman kazandırır.

Draft versiyonu seçimi doğrulama davranışını etkiler. Draft 7 (en köklü sürüm, aynı zamanda kütüphane desteği en geniş olanı) mevcut projelerde güvenli seçimdir. Draft 2019-09 ve 2020-12, referans yönetimi ve unevaluatedProperties gibi gelişmiş özellikler sunar; ancak tüm kütüphaneler bu sürümleri tam olarak desteklemez. Kullanılan kütüphanenin hangi draft'ı desteklediğini belgeden doğrulamak, sürüm uyumsuzluğundan kaynaklanan sessiz hataları engeller.

Şema geçerliliğini test etmek için meta-schema kavramına başvurulabilir: JSON Schema organizasyonunun yayımladığı meta-şema, bir şemanın kendisinin geçerli JSON Schema olup olmadığını doğrular. Yani şema aynı zamanda başka bir şemayla doğrulanabilir; bu, büyüyen şema dosyalarında yapısal tutarlılığı korumak için kullanışlı bir yaklaşımdır.

JSON verisi içinde binary içerik taşınması gerektiğinde, örneğin görsel veya dosya verisi bir API yanıtında iletilmek istendiğinde, bu içerik genellikle string olarak kodlanır. Bu durum şema tasarımını doğrudan etkiler: binary veri Base64 kodlamasına dönüştürülerek string tipinde bir alan olarak tutulur ve şemada "type": "string" ile tanımlanır. Kütüphanenin format: "byte" keyword'ünü destekleyip desteklemediği ayrıca kontrol edilmelidir; desteklemiyorsa bu format kısıtlaması sessizce atlanır ve geçersiz bir kodlama yanlışlıkla kabul edilir.

Veri doğrulama zinciri; şema tasarımı, kütüphane seçimi ve hata mesajının yorumlanmasından oluşur. Üç adımın herhangi birinde bir boşluk bırakılırsa doğrulama ya fazla izin verir ya da gereksiz yere engel çıkarır. JSON Schema bu zincirin yalnızca ilk halkasını oluşturur; nasıl yazıldığı, kullanılan kütüphanenin hangi keyword'leri uyguladığı ve hata çıktısının nasıl yorumlandığı diğer halkalar kadar belirleyicidir.