Go'da JSON marshaling standart olarak encoding/json paketi üzerinden gerçekleştirilmektedir. Sadece dışa aktarılan (büyük harfle) alanlar serileştirilebilir. İsimler üzerinde kontrol sağlamak ve işleme yapmak için struct etiketleri kullanılır:
type User struct { ID int `json:"id"` Name string `json:"name,omitempty"` Age int `json:"age,string"` }
omitempty sıfır değerinde alanı hariç tutar;string değeri bir sayı olsa bile string olarak serileştirir.user := User{ID: 1, Name: "Oleg"} b, _ := json.Marshal(user) fmt.Println(string(b)) // {"id":1,"name":"Oleg","age":"0"}
var u User json.Unmarshal([]byte('{"id":2,"name":"Ivan"}'), &u)
JSON'da marshaling sırasında dışa aktarılmayan (küçük harfle) alanlar nasıl serileştirilir?
Doğru cevap: İgnore edilir, yalnızca dışa aktarılan (büyük harfle) alanlar serileştirmeye katılır. Bu sık sık API'yi aniden bozabilir:
type Foo struct { bar int // serileştirilmeyecek! }
Hikaye
Backend eksik JSON nesneleri sağlıyordu çünkü bazı gerekli alanlar dışa aktarılmamıştı (küçük harfle). Müşterilerin bu alanları neden görmediğini anlamak birkaç gün sürdü.
Hikaye
API yanıtında alan omitempty yapısını içeriyordu, ancak bazen boş değer geliyordu çünkü dilim için sıfır değeri nil'dir, boş bir dilim değil. Müşteriler null yerine boş dizi [] alıyor ve ayrıştırma sırasında hataya düşüyordu.
Hikaye
Projede dinamik alanlar struct'lara map[string]interface üzerinden ekleniyordu, ancak özel bir UnmarshalJSON uygulamak unutuluyordu, bu yüzden bazı veriler "kayboluyordu" hata olmadan. Müşteri verileri kayboluyor ve manuel olarak yedeklerden geri yükleniyordu.