JSON’dan Go’ya

JSON’dan json etiketli Go struct’ları üretir: sayı türü yazılışa göre seçilir, eksik olabilecek değerler işaretçi olur — tümü tarayıcınızda.

Girdi
Go
type Root struct {
	Orders  []Order `json:"orders"`
	HasMore bool    `json:"has_more"`
}

type Order struct {
	ID        int64    `json:"id"`
	UserID    int64    `json:"user_id"`
	CreatedAt string   `json:"created_at"`
	Price     float64  `json:"price"`
	Coupon    *string  `json:"coupon"`
	GiftNote  *string  `json:"gift_note,omitzero"`
	Shipping  Shipping `json:"shipping"`
	Tags      []any    `json:"tags"`
}

type Shipping struct {
	City     string          `json:"city"`
	Postcode json.RawMessage `json:"postcode"`
}
  • Aşağıdaki her konumda her sayı tam sayı olarak okundu, bu yüzden türü int64’tür. Go, ondalık noktası ya da üs içeren bir değeri, 10.0 bile olsa, bu türe almayı reddeder.

    Konumlar: 2

    • Order.ID
    • Order.UserID
  • Aşağıdaki her konumda değerler birden fazla türde — örneğin sayılar ve metinler — bu yüzden tür olarak json.RawMessage seçildi: her değer JSON’unuzda yazıldığı gibi saklanır ve programınız hangi türde olduğunu öğrendiğinde onun kodunu çözer. Türlerden biri nesneyse, onun struct’ı çıktıda yine yer alır ve o değerin kodu bu struct’a çözülebilir.

    Konumlar: 1

    • Shipping.Postcode
  • Aşağıdaki her konumda tür çıkarılabilecek hiçbir şey yoktu: orada yalnızca null görüldü, dizi her zaman boştu, nesnenin hiç anahtarı yoktu ya da değer bu aracın izleyemeyeceği kadar derinde iç içe. Bu yüzden tür olarak any seçildi; bu tür her değeri kabul eder. Nesnenin hiç anahtarı olmadığı yerde ise map[string]any seçildi; bu tür her nesneyi ve null değerini kabul eder, başka hiçbir değeri kabul etmez.

    Konumlar: 1

    • Order.Tags[]

Türetildikleri JSON’un kodunu çözen struct’lar

Bir JSON örneği yapıştırın; bu sayfa onun için Go tanımları yazar: örnekteki her nesne için adlandırılmış bir struct ve her alanda, o alanın okuduğu anahtarı adlandıran bir json etiketi. Aşağıdaki her şeyi tek bir söz belirler. Go 1.27 ile derlenen bir programa konduklarında tanımlar, yapıştırdığınız JSON’un kodunu "encoding/json" paketi üzerinden hatasız çözer ve hiçbir struct etiketinin taşıyamayacağı bir anahtar dışında her anahtar bir alana okunur; böyle bir anahtar struct’ın dışında bırakılır. Go’nun bu sözün tutmasına izin vermediği ya da sayfayı verilerinizin karar vermediği bir şeyi seçmeye zorladığı yerde, çıktının altındaki bir bildirim bunun nerede olduğunu söyler; bunun nadir bir istisnası vardır ve etiketlerle ilgili bölümde anlatılır.

Biçimin kendisi daha hiçbir Go yazılmadan çıkarılır; bunu yapan, JSON’unuzun JSON’dan TypeScript’e sayfasını besleyen aynı okumasıdır. Bir dizinin öğelerini birleştirmek, yalnızca bazılarında bulunan anahtarları fark etmek, null’ı hiç gönderilmemiş bir anahtardan ayırmak ve başka bir nesnenin içinde bulunan her nesneye ad vermek: o sayfanın kılavuzu bunların hepsini ele alır, bu yüzden aşağıda hiçbiri tekrarlanmaz. Bundan sonrası Go’nun payına düşen kısımdır — her sayı için bir tür, işaretçiler, farklı türlerde değerleri olan bir anahtar için bir tür, alan adları, etiketler ve bildirimlerin doğurduğu sorular.

Her sayının nasıl yazıldığına göre seçilen üç sayı türü

JSON okuyan bir tarayıcı 10 ile 10.0’ı aynı sayıya çevirir. Go öyle yapmaz: "int64" türündeki bir alan, ondalık noktası ya da üsle yazılmış bir sayıyı — 10.0, 1e3, hatta -0.0 — reddeder, 11’i ve -0’ı ise kabul eder. Bu yüzden sayfa bir sayı türünü yalnızca değerlere bakarak seçmez. Tarayıcının kendi ayrıştırıcısına her sayının nasıl yazıldığını sorar ve buna göre karar verir:

  • Bir konumdaki her sayı ondalık noktası ve üs olmadan, tam sayı olarak yazılmışsa alan "int64" türündedir ve tam sayılar bildirimi onu adıyla anar.
  • Başka her sayı "float64" türündedir; yani 10.0 diye yazılmış bir fiyat, örnekteki her fiyat yuvarlak olsa bile "float64" türündedir. Python’un "json" modülü değeri tam sayı olan float sayıları tam olarak böyle yazar; bu da Python ile sunulan bir API’yi bununla genellikle karşılaşılan yer yapar.
  • "json.Number" türü, iki türün de tam olarak tutamadığı sayılara ayrılmıştır: "int64" aralığının iki ucundan birinin ötesindeki bir tam sayı, 1e999 gibi, bir "float64" türüne hiç sığmayacak kadar büyük bir sayı ve [9007199254740993, 1.5] dizisindeki gibi, bir kesrin yanında duran ve bir "float64" türü için fazla uzun olan bir tam sayı. Bu tür her birini tam olarak tutar; programınız da değeri kullandığı yerde onu dönüştürür.

Başka tam sayıların arasındaki uzun bir tam sayı böyle bir özen gerektirmez: [9007199254740993, 1] bir "[]int64" türüdür. Bir "float64" türünün tuttuğundan fazla basamağı olan bir kesir "float64" olarak kalır ve kendi bildiriminde adıyla anılır, çünkü 0.30000000000000001, kodu çözülüp yeniden kodlandığında 0.3 olarak geri gelir.

Bir sayının nasıl yazıldığını okumak, bunu bildiren bir tarayıcı gerektirir. Bildirmeyen bir tarayıcı her sayıyı yalnızca değerinden okur, bu yüzden orada 10.0 tam görünür ve alanı, o JSON’un kodunu çözemeyecek bir "int64" türünü alır; sayfa tam sayılardan ayırt edemediği sayıları sayar ve ilkinin nerede olduğunu gösterir. Böyle bir tarayıcı bir "float64" türünün attığı basamakları da göremez; bu yüzden orada bir kesrin yanındaki uzun bir tam sayı "float64" türünü alır ve yuvarlanan bir kesir adıyla anılmaz.

Değerin eksik olabileceği yerde işaretçiler

Bazı nesnelerin dışarıda bıraktığı ya da null yaptığı bir anahtar bir işaretçidir: "*string", "*int64" ya da bir nesne için yazılmış struct’ı gösteren bir işaretçi. İçinde null bulunan bir dizinin öğeleri de işaretçidir; bu yüzden [1, null] bir "[]*int64" türüdür. Bazı nesnelerde bulunmayan bir anahtar ayrıca etiketinde "omitzero" seçeneğiyle işaretlenir. İkisi birlikte olduğunda bir alan bir değerin gelip gelmediğini söyleyebilir; kodu çözülmüş struct yeniden kodlandığında da, örnekte hep yalnızca eksik bırakılmış bir anahtar yine atlanır, hep yalnızca null yapılmış bir anahtar da yine null olarak yazılır.

Bir slice, bir map, "any" ve "json.RawMessage" işaretçi almaz, çünkü içine hiçbir şeyin kodu çözülmediğinde her biri zaten nil olur. Yine de bir slice, anahtarının eksik olabileceği yerde "omitzero" alır; var olan ama boş olan bir dizi de yeniden [] olarak yazılır.

Bir ayrım korunmaz. Bazı nesnelerde bulunmayan ve başka nesnelerde null olan bir anahtar Go’da tek bir nil’dir; bu yüzden programınız bu ikisini ayırt edemez ve struct yeniden kodlandığında anahtar, örnekte null olduğu yerde bile atlanır; sayfa bunun olduğu her alanı adıyla anar. Karışık türlerde değerleri olan bir anahtar farkı korur, çünkü bir "json.RawMessage" null’ı null baytları olarak tutar.

Karışık türler için json.RawMessage, hiçbir şey görülmeyen yerde any

Bir anahtarın değerleri türde uyuşmadığında — bir yerde bir sayı, başka bir yerde bir metin ya da bir nesne — alan "json.RawMessage" türündedir: değerin kendi baytları, programınız hangi türün geldiğine baktıktan sonra kodunu çözsün diye ona bırakılır. Aralarındaki bir null hiçbir şeyi değiştirmez. Türlerden biri nesne olduğunda, onun için çıkarılan struct yine de ötekilerin yanında yazdırılır. Bir "any" türü de her türü kabul ederdi ve karışık türler için kullanılmaz, çünkü bir "any" türüne kodu çözülen bir sayı "float64" olur ve bir "float64" türünün tutamadığı her şeyi yitirir.

Bir örnekteki bazı kısımlar öğrenilecek hiçbir değer sunmaz: hep yalnızca null tutmuş bir anahtar, her seferinde boş olan bir dizi, anahtarı olmayan bir nesne ve çıkarımın okuduğundan daha derinde iç içe geçmiş bir değer. Go’da null anahtarı ile o derinlikteki değer "any", boş dizinin öğeleri "[]any", nesne de "map[string]any" türünü alır. Bir "any" türü her türden değeri kabul eder. Map bir nesneyi ya da null’ı kabul eder; onun yerine bir metin, bir sayı, bir dizi ya da bir mantıksal değer gelirse kod çözme başarısız olur.

O derinliğin ötesinde iki şey bildirimlerde dile getirilmez. Orada bazı nesnelerde bulunmayan ve başka nesnelerde null olan bir anahtar, yalnızca tür çıkarılabilecek hiçbir şeyin olmadığı bir konum olarak adıyla anılır ve Go, o null değerini geri yazarken anahtarı atlar. Ayrıca bir "float64" türünün tuttuğundan uzun bir tam sayı yuvarlanmış olarak geri gelir: 9007199254740993 sayısı 9007199254740992 olarak döner, çünkü o konum bir "any" türüdür.

Go üslubunda alan adları, TypeScript sayfasıyla ortak struct adları

Bir alanın adı, anahtarının Go’daki yazılışıdır. Anahtar, harf ya da rakam olmayan her karakterde ve küçük bir harfin ardından büyük bir harf geldiği her yerde sözcüklere bölünür; sonra sözcükler, her biri büyük harfle başlayarak bitiştirilir, böylece "user_name", "last-name" ve "firstName" anahtarları UserName, LastName ve FirstName olur. Bir sözcük staticcheck’in varsayılan kısaltma listesindeyse büyük harflerle yazılır — "id" ID olur, "api_key" APIKey olur, "video_url" VideoURL olur — ama yalnızca bütün bir sözcük sayılır, bu yüzden "idle" Idle olur ve çoğul "ids" de Ids olur. Tümüyle büyük harflerle yazılmış bir anahtar sözcükler olarak okunur: "USER_ID" UserID olur.

Anahtarın kendi harfleri korunur, bu yüzden "имя" Имя olur. Bir ad büyük harfle başlamayacaksa — "名前" gibi büyük harfsiz bir yazı sistemindeki bir anahtar, "1st" gibi rakamla başlayan bir anahtar ya da "ß" gibi büyük hâli tek bir harf olmayan bir ilk harf — adın önüne bir X eklenir ve ad X名前, X1st ve Xß olur; alan anahtarını yine de okur. Birleştirici işaretler addan çıkarılır ve etikette korunur. "@" gibi hiç harf ya da rakam içermeyen bir anahtarın adı Field olur ve aynı struct’ta zaten kullanılmış bir ad bir sayı alır: "user_id", "userId" ve "USER_ID" birlikte UserID, UserID2 ve UserID3 olur.

Go üslubu alan adlarına kadar uzanır ve orada durur: her struct, nesnesi için çıkarımın seçtiği adı korur; bu yüzden buradaki tanımlar ile TypeScript sayfasındaki arayüzler aynı adları taşır ve bir alan, tuttuğu struct’tan farklı yazılabilir. O adın nasıl seçildiği TypeScript kılavuzuna aittir.

Go 1.27 için etiketler ve hiçbir etiketin taşıyamayacağı anahtarlar

Her alanın etiketi anahtarını tam olarak adlandırır, json:"user_id" gibi; anahtarın eksik olabileceği yerde anahtardan sonra ,omitzero gelir. Bir anahtardaki denetim karakteri Go’nun kendi kullandığı kaçış dizisiyle yazılır ve "-" anahtarı json:"-," olarak yazılır; Go bu biçimi o anahtar olarak okur.

Etiketler Go 1.27 için yazılır. Go 1.26 bir etiket üzerinden daha az anahtar okur: harflerden, rakamlardan, ASCII boşluğundan ve bir takım ASCII noktalama işaretinden başka bir şey içeren bir anahtar — "Price (€)", "temp °C", bir emoji, bir denetim karakteri, birleştirici bir aksan — orada okunmaz ve sayfa böyle her alanı adıyla anar. Bu yarı, "GOEXPERIMENT=nojsonv2" ile derlenmiş Go 1.27’ye karşı denetlenir; bu derleme etiketleri Go 1.26 gibi okur ama Go 1.27’nin daha yeni Unicode tablolarıyla okur, bu yüzden Go 1.26’nın eski tablolarında bulunmayan bir harf içeren bir anahtar bu denetimde okunur ve hiçbir bildirim doğurmaz.

Virgül, ters eğik çizgi, çift tırnak, kesme işareti veya ters tırnak içeren bir anahtar ya da boş anahtar, hiçbir struct etiketinin taşıyamayacağı bir anahtardır; bu yüzden hiç alan almaz. JSON’unuzun kodu yine de çözülür: "json.Unmarshal" bu anahtarı şikâyet etmeden atlar, ancak "DisallowUnknownFields" seçeneği ayarlanmış bir "json.Decoder" bu anahtarda durur. Bildirim böyle bir anahtarı struct’ı ve Go’nun bir metni tırnak içine aldığı biçimde tırnaklanmış anahtarla birlikte listeler, Order["note,internal"] gibi; böyle bir anahtarın altındaki bir nesnenin struct’ı da yine yazdırılır. Bir durum bildirimsiz geçer: yalnızca tek başına bir vekilde, yani hiçbir karaktere karşılık gelmeyen bir kaçış dizisinde farklılaşan iki anahtar Go için tek bir anahtardır ve bu anahtarların alanlarından hiçbiri doldurulmaz.

Yalnızca tanımlar, gofmt düzeninde

Çıktı tür tanımlarından başka bir şey içermez: ne package satırı ne de import satırı vardır; bu yüzden elinizdeki bir dosyaya, o dosyanın kendi package satırının altına girer. Çıktının "json.RawMessage" ya da "json.Number" kullandığı yerde dosya ayrıca "encoding/json" paketini içe aktarır ve size ya da düzenleyicinize kalan satır budur. Düzen, gofmt aracının kendi düzenidir — her alanın önünde bir sekme, her struct’ın adları, türleri ve etiketleri de hizalanmış sütunlarda — bu yüzden gofmt onu tam olarak olduğu gibi bırakır. Kökün türü ilk sırada yazdırılır, her nesne onu tutan alanın içine yazılmış bir struct değil, adlandırılmış bir türdür ve en üst düzeyde bir dizi ya da tek bir değer olan JSON da "type Root []RootItem" gibi adlandırılmış bir türdür; böylece JSON’un kodunun çözülebileceği bir tür her zaman vardır.

Bildirimlerin denetlemenizi istediği şeyler

Go’nun dayattığı her karar çeşidi tanımların altında bir giriş alır ve bu giriş geçerli olduğu her yeri bir araya toplar; böylece çok sayıda tam sayı alanı olan bir örnek, alan başına bir giriş değil, tek bir giriş alır. Yerler tanımların yazdığı gibi yazılır — Order.UserID bir alandır, Order.Tags[] bir dizinin öğeleridir, kök de yalın adıdır — bunun yerine JSON’unuzun içini satır ve sütunla gösteren iki giriş dışında: iki kez yazılmış bir anahtar ve bu tarayıcının tam sayılardan ayırt edemediği sayılar. Bunların hiçbiri tanımları değiştirmez. Her birini verileriniz hakkında bir soru olarak okuyun:

  • "int64" türü verilmiş tam sayılar. Oradaki her sayı tam yazılmıştı. Sonradan gelen bir değer, bir fiyatın ya da bir ölçümün taşıyabileceği gibi ondalık noktası ya da üs taşıyabilecekse kodu çözülmez, bu yüzden o alanı "float64" yapın; bir ID ya da bir sayım olduğu gibi kalabilir.
  • "json.Number". Başka hiçbir sayı türü bu değerleri tam olarak tutmaz. Her birini programınızın kullandığı yerde dönüştürün ya da gerçek değerlerin daha dar bir türe sığdığını biliyorsanız alanı kendiniz değiştirin.
  • "float64" türünün yuvarladığı bir kesir. Oradaki bir sayının bir "float64" türünün tuttuğundan fazla basamağı vardır; bu yüzden programınız yazılan değeri değil, ona yakın bir değeri görür. Her basamağın önemli olduğu yerde alanı "json.Number" yapın.
  • "json.RawMessage" olarak saklanan karışık türler. Her değere geldiğinde bakın ve kodunu, ortaya çıkan türüne göre çözün; türlerden biri nesneyse, onun struct’ı çıktıda yine yer alır ve o değerin kodu bu struct’a çözülebilir.
  • Tür çıkarılabilecek hiçbir şey yok. Alan "any" türündedir ya da değerleri "any" olan bir map türündedir, çünkü örnekte orada öğrenilecek hiçbir değer yoktu. Onu, o alanın taşıdığını bildiğiniz türle değiştirin ya da alanın gerçek değerler taşıdığı bir JSON’dan yeniden dönüştürün.
  • Bazı nesnelerde yok, bazılarında null. Go ikisi için tek bir nil tutar; bu yüzden anahtar geri yazılırken atlanır. Bu, yalnızca çıktınızı okuyan şey null’ı orada olmayan bir anahtardan farklı ele alıyorsa önemlidir.
  • Go 1.26’nın okumadığı anahtarlar. Go 1.27 ile derleyin ya da bu anahtarları üretildikleri yerde yeniden adlandırın; Go 1.26’da okunmadan kalırlar.
  • Struct’ın dışında bırakılan anahtarlar. Bunların alanı yoktur. Birini okumak için, bildirimin kendisinin önerdiği gibi, nesnenin kodunu bir "map[string]json.RawMessage" olarak çözün ya da struct için bir "UnmarshalJSON" yöntemi yazın.
  • İki kez yazılmış bir anahtar. Türler anahtarın son kopyasını izler, ama Go her kopyanın kodunu sırayla çözer; bu yüzden türün tutamayacağı önceki bir kopya, son kopya sayıyken gelen bir metin gibi, kod çözmenin hata döndürmesine yol açar ve bir nesnenin yalnızca önceki bir kopyasında bulunan bir anahtar okunmaz. JSON’u gösterilen satırda ve sütunda düzeltin.
  • Bu tarayıcı 10 ile 10.0’ı ayırt edemiyor. Bir sayının nasıl yazıldığını bildirmez; bu yüzden ondalık noktası ya da üsle yazılmış bir değer yüzünden "int64" türünü almış bir alan JSON’unuzun kodunu çözemez. Bu şekilde yazılmış alanları denetleyin ya da JSON’u bunu bildiren bir tarayıcıda dönüştürün.

Tarihler, biçimler ya da sabit değer kümeleri hakkında bildirim yoktur, çünkü sayfa bir metinden bunlardan birini asla tahmin etmez: sayfanın yüklediği örnekteki "created_at" anahtarı, neye benzerse benzesin "string" türünde kalır.

Sıkça sorulan sorular

JSON’umdaki her fiyat yuvarlak bir sayıyken fiyatım neden float64?
Çünkü her fiyat 10.0 gibi ondalık noktasıyla yazılmıştır ve "int64" türündeki bir alan, yuvarlak olsun olmasın, böyle yazılmış bir sayıyı reddeder. Sayfa her sayının yalnızca değerini değil, nasıl yazıldığını da okur; bu yüzden alan "float64" türündedir ve JSON’unuzun kodu çözülür. Tür yalnızca değerlere bakılarak "int64" seçilseydi, kod çözme ilk fiyatta dururdu.
Bir sayı ne zaman json.Number olarak çıkar?
Değerlerinden biri "int64" aralığının ötesinde bir tam sayı, bir "float64" türü için fazla büyük bir sayı ya da bir "float64" türünün yuvarlayacağı, bir kesrin yanında duran uzun bir tam sayı olduğunda. "json.Number" türü bunların her birini tam olarak korur ve çıktının altındaki bildirim, bu türün seçildiği her alanı listeler.
Bazı alanlar neden işaretçi, etiketlerdeki omitzero da ne yapıyor?
Bir alan, anahtarının bazı nesnelerde bulunmadığı ya da bazılarında null olduğu yerde işaretçidir; böylece bir nil hiçbir değerin gelmediğini söyleyebilir. "omitzero" seçeneği, anahtarın bazı nesnelerde bulunmadığı yere konur: struct yeniden kodlandığında o anahtar, onun için null yazılmak yerine JSON’unuzda olduğu gibi atlanır.
Karışık türlerde değerleri olan bir anahtar için neden any değil de json.RawMessage?
Bir "json.RawMessage" türü, programınız onları nasıl okuyacağına karar verene kadar her değerin baytlarını saklar. Bir "any" türü de değerleri kabul ederdi, ama bir "any" türüne kodu çözülen bir sayı bir "float64" türüdür ve uzun bir tam sayı orada son basamaklarını yitirir.
Bazı alan adları neden bir X ile başlıyor?
Çünkü aksi hâlde ad büyük harfle başlamazdı: anahtar büyük harfsiz bir yazı sistemiyle yazılmıştır, bir rakamla başlar ya da büyük hâli tek bir harf olmayan bir harfle başlar. X, anahtarın kendi harflerini adda tutar ve alan anahtarını yine okur — X名前, "名前" anahtarını okur.
Struct’lar Go’nun hangi sürümüne ihtiyaç duyar?
Bunlar Go 1.27 için yazılır ve denetlenir. Go 1.26’nın etiketleri nasıl okuduğu da, onun yerini tutan bir şey üzerinden denetlenir: Go 1.26, harflerin, rakamların, ASCII boşluğunun ve bir takım ASCII noktalama işaretinin dışında kalan, bir para birimi simgesi ya da bir emoji gibi bir karakter içeren bir anahtarı okumaz ve sayfa anahtarı bundan etkilenen her alanı adıyla anar — Go 1.26’nın Unicode tablolarından daha yeni bir harf içeren bir anahtar hariç; böyle bir anahtarı ne sayfa ne de o denetim görebilir.
Anahtarlarımdan biri struct’ta neden yok?
Çünkü anahtar virgül, ters eğik çizgi, çift tırnak, kesme işareti veya ters tırnak içeriyor ya da boş ve hiçbir struct etiketi böyle bir anahtarı taşıyamaz. Bir bildirim onu struct’ı ve anahtarın kendisiyle listeler, Root["a,b"] gibi; JSON’unuzun geri kalanının kodu yine de çözülür ve bildirim o anahtarı başka bir yolla nasıl okuyacağınızı söyler.
Token ya da parola içeren bir yanıtı yapıştırmak güvenli mi?
Evet. Her adım bilgisayarınızda, bu sayfanın içinde çalışır ve yapıştırdığınız yanıt başka hiçbir yere gitmez: hiçbir sunucu onu almaz ve hiçbir şey bir kopyasını tutmaz. Ondan üretilen tanımlar yalnızca alan adları, etiketler ve Go türleri taşır; bu yüzden JSON’daki bir token ya da parola, anahtarının adını taşıyan bir "string" alanı dışında onlarda hiçbir iz bırakmaz.

İlgili araçlar

  • JSON’dan TypeScript’e

    Bir anahtarın değerleri birden fazla türde olduğunda bu sayfa, Go’da union olmadığı için her değeri JSON’unuzda yazıldığı gibi saklar ve kodunu çözmeyi programınıza bırakır. O sayfa aynı biçimi aynı tür adlarıyla TypeScript türleri olarak yazar, orada bir union kullanır ve bu biçimin nasıl çıkarıldığını kendi kılavuzunda anlatır.

  • JSON’dan Zod’a

    Go’da yalnızca bir JSON sayısı olan bir tür yoktur, bu yüzden bu sayfa her sayının tam sayı olarak yazıldığı yerde alana bir tam sayı türü verir ve Go, ondalık noktası içeren bir değeri bu türe almayı reddeder. O sayfa aynı biçimi aynı tür adlarıyla Zod şemaları olarak yazar; bir şema veriyi her geldiğinde denetler ve böyle bir alanda bir kesri de kabul eder.

  • JSONPath test aracı

    RFC 9535 JSONPath sorgularını JSON’a karşı test edin.

  • Markdown tablo oluşturucu

    CSV, TSV veya JSON verisinden Markdown tablosu oluşturun.