Giriş
Bu yazıda Golang ve JSON’lar ile nasıl çalışılır onu göstereceğim. Golang diğer dillere göre biraz daha farklı, kısmen dogmatik bir dil. Kullanımda şart koştuğu bazı standartları nedeniyle kısmen dogmatik dememde bir sakınca yok sanıyorum.
Çoğu yazılım geliştirici JSON verilerle çalışmıştır. Günümüzde SPA’lerin artışı ve RESTful API’ların da aynı şekilde yükselişiyle birlikte JSON veri kullanımı kaçınılmaz hale gelmiştir.
Twitter, Facebook, Reddit, YouTube, GitHub, Spotify ve daha birçok büyük kuruluş, geliştiricilere verilerini sunarken birçok seçeneği de beraberinde getirmekte. Bu seçeneklerden en popüleri kuşkusuz ki JSON. Go programlama dilinin JSON için desteği de kuşkusuz ki bulunmaktadır.
Her ne kadar en hızlı JSON parser D dilinde yazılmış olsa da bu çok fazla da bir şeyi etkilemeyecektir.
Gelişme
Go programlama dilinde JSON oluşturmak için encoding/json
paketine ihtiyaç duyarız. Bu JSON veri oluşturmanın en kolay yolu oluyor Golang için. Golang’de JSON oluştururken göz önünde bulundurmamız gereken bazı noktalar var. Bunlardan en önemlisi veri türünün doğru bir şekilde seçilmesi.
Strucları Kullanmak
Go dilinde structlar bir hayli kullanışlıdır. Eğer map ya da daha karmaşık yapılarla karşılaştıracak olsaydık maliyetinin daha iyi olduğunu söyleyebilirdik.
Herhangi bir struct’ın örneğini json.Marshal
isimli metoda aktarabilir ve JSON’u baytın dilimleri halinde geri alabilirsiniz.
type Musteriler struct { Adi string Soyadi string Yasi int Telefon []string }
Elimizde yukarıdaki bir yapımızın olduğunu varsayalım. Bu yapı müşterinin bilgilerini tutmakta. Sadece telefon alanı birden fazla olabilir durumda.
Bu yapıya veri ekleyelim ve yazdıralım.
func main() { musteri := Musteriler { Adi: "Ali", Soyadi: "GOREN", Yasi: 24, Telefon: []string{"000 111", "123456"}, } json_bytelar, _ := json.Marshal(musteri) fmt.Printf("%s", json_bytelar) } /* {"Adi":"Ali","Soyadi":"GOREN","Yasi":24,"Telefon":["000 111","123456"]} */
Yazdırdığımızda ayrıca yukarıdaki çıktıyı alırız.
Bu kısım için uyarılar şunlar;
- Alan isimleri büyük harfle başlamalı.
- Farklı yapıları iç içe olacak şekilde kullanabilirsiniz. Örneğin e postalar
json.Marshal
metodu hem JSON veriyi hem de hatayı döndürür. Yani hatayı mutlaka gelecekmiş gibi handle etmelisiniz. Normalde Marshal metodu hata döndürmemekte. Ancak hata dönen durumlardan birisi, bazı türlerin JSON’a dönüştürülememesi ki bu durumda hata dönebilir.- Geri dönen JSON byte listesi biçiminde döneceği için eğer string olarak kullanmak istiyorsanız dönüştürmeniz gerekecektir.
- Structlara veri girildikten sonra en son elemandan hemen sonra virgül koymayı unutmayın. Aksi durumda hata alırsınız.
İsim Alanlarını Kullanın
Bu önemli bir konu. Yukarıdaki örneğimizde çıktıda tüm keyler büyük harfle başlıyordu. Böyle bir şey olmasını istemiyorsanız aliaslar kullanabiliriniz. Bu bir bakıma SQL’de yer alan SELECT Adi as adi FROM Musteriler
kullanımına eş değerdir.
https://stackoverflow.com/questions/10858787/what-are-the-uses-for-tags-in-go
O halde yukarıdaki örneğimizde yer alan struct’a bazı eklemeler yapalım.
type Musteriler struct { Adi string <code>{{EJS0}}</code> Soyadi string <code>{{EJS1}}</code> Yasi int <code>{{EJS2}}</code> Telefon []string <code>{{EJS3}}</code> }
Bu işlem sadece api endpoint durumlarında son kullanıcıya baş harfleri ufaltılmış keyler sunacaktır. Keyleri de küçük yazmayın.
Boş Alanları Yok Etmek
Normalde bu alanların tamamının veri alacağını düşünürüz. Ancak her zaman hepsinin içeriğinin dolu olup olmayacağına dair bir garanti veremeyebiliriz.
Bu gibi durumlar için omitempty
isimli bir flag imdadımıza yetişiyor. Örneğin şöyle bir örnek yaparsak:
func main() { musteri := Musteriler {} json_bytelar, _ := json.Marshal(musteri) fmt.Printf("%s ", json_bytelar) } /* {"adi":"","soyadi":"","yasi":0,"telefonlar":null} */
Çıktısı örnekteki gibi görünür. Aynı işlemi structımıza omitempty
flagini ekleyerek yapalım:
type Musteriler struct { Adi string <code>{{EJS4}}</code> Soyadi string <code>{{EJS5}}</code> Yasi int <code>{{EJS6}}</code> Telefon []string <code>{{EJS7}}</code> } func main() { musteri := Musteriler { Adi: "Ali", } json_bytelar, _ := json.Marshal(musteri) fmt.Printf("%s ", json_bytelar) } /* {"adi":"Ali"} */
Sadece veri tanımlanmış olan struct elemanının çıktısını verildiğini görmekteyiz. Bu bazı durumlarda dinamik generate edilen json keylerinin çalışmasına örnek olabilir.
Alanları Atlamak
Yukarıdaki durumun bir başka versiyonu ise alanlar dolu olsa dahi hepsinin yansıtılmaması üzerine kurulu senaryodan ibaret.
Bu durumda -
flagini kullanarak dolu dahi olsa bu alanı gösterme sadece sakla diyebiliriz. Yine bu flagi structimizda gösterelim ve yaş alanını değiştirelim:
type Musteriler struct { Adi string <code>{{EJS8}}</code> Soyadi string <code>{{EJS9}}</code> Yasi int <code>{{EJS10}}</code> Telefon []string <code>{{EJS11}}</code> } func main() { musteri := Musteriler { Adi: "Ali", Yasi: 24, } json_bytelar, _ := json.Marshal(musteri) fmt.Printf("%s ", json_bytelar) } /* {"adi":"Ali"} */
Görüldüğü üzere yaş alanı geri döndürülen JSON verisinde yer almamakta.
Sonuç
Bu yazıda JSON verilerle nasıl çalışılacağını gördük. Bu yazı şu anda sadece structlar üzerinden JSON datasının json.Marshal
metodunu kullanarak nasıl üretileceği göstermekte.
Ayrıca bir parça da Golang’in dogmatik yapısını anlamamıza da yardımcı oldu.