Struct tag omitempty adalah fitur penting dalam bahasa pemrograman Go, khususnya saat melakukan encoding dan decoding data ke format JSON menggunakan package encoding/json. Tag ini memberikan instruksi kepada encoder JSON untuk mengabaikan field struct jika nilainya kosong (zero value) saat proses encoding.

Apa Itu omitempty?

Secara default, ketika kita melakukan encoding struct ke JSON, semua field akan disertakan, meskipun nilainya kosong. Dengan menambahkan tag omitempty, field tersebut tidak akan dimasukkan ke dalam hasil encoding JSON jika nilainya adalah zero value untuk tipe datanya (misal: "" untuk string, 0 untuk int, nil untuk pointer/slice/map, dll).

Permasalahan Tanpa omitempty

Salah satu masalah yang sering ditemui adalah ketika field pada struct bersifat opsional. Jika field tersebut tidak diisi pada data request dari klien, maka setelah proses decoding (unmarshal), field tersebut akan berisi nilai default (zero value). Namun, saat encoding kembali ke JSON, field tersebut tetap akan muncul dengan nilai kosong.

Sebagai contoh, perhatikan struct berikut:

type Car struct {
	Manufacturer string `json:"manufacturer"`
	Color        string `json:"color"`
}

Jika kita melakukan parsing JSON berikut ke struct di atas:

rawJSONCar := `
	{
		"manufacturer": "BMW"
	}
`

var car Car
err := json.Unmarshal([]byte(rawJSONCar), &car)
if err != nil {
	panic(err)
}

fmt.Printf("%+v\n", car)

Output di terminal:

$ go run main.go
{Manufacturer:BMW Color:}

Field Color tetap ada di struct, namun nilainya adalah string kosong (""). Jika kita melakukan encoding struct ini kembali ke JSON:

carBytes, err := json.Marshal(car)
if err != nil {
	panic(err)
}

fmt.Println(string(carBytes))

Output JSON:

{ "manufacturer": "BMW", "color": "" }

Field color tetap muncul meskipun nilainya kosong.

Solusi dengan omitempty

Untuk mengatasi masalah tersebut, gunakan tag omitempty pada field yang bersifat opsional:

type Car struct {
	Manufacturer string `json:"manufacturer"`
	Color        string `json:"color,omitempty"`
}

Jika kita encode struct berikut:

car := Car{
	Manufacturer: "BMW",
}

carBytes, err := json.Marshal(car)
if err != nil {
	panic(err)
}

fmt.Println(string(carBytes))

Output:

{ "manufacturer": "BMW" }

Field color tidak muncul karena nilainya kosong.

Jika field Color diisi:

car := Car{
	Manufacturer: "BMW",
	Color:        "Black",
}

carBytes, err := json.Marshal(car)
if err != nil {
	panic(err)
}

fmt.Println(string(carBytes))

Output:

{ "manufacturer": "BMW", "color": "Black" }

Field color muncul karena nilainya tidak kosong.

Catatan Penting

  • omitempty hanya berpengaruh saat encoding (marshal) ke JSON, bukan saat decoding (unmarshal).
  • Zero value berbeda untuk setiap tipe data:
    • String: ""
    • Int: 0
    • Bool: false
    • Pointer, slice, map, interface: nil
  • Jika ingin membedakan antara “field tidak ada” dan “field ada tapi nilainya kosong”, gunakan pointer pada field struct.

Contoh:

type Car struct {
	Manufacturer string  `json:"manufacturer"`
	Color        *string `json:"color,omitempty"`
}

Dengan cara ini, Anda bisa membedakan antara field yang tidak dikirim (nil) dan field yang dikirim dengan nilai kosong ("").

Kesimpulan

Penggunaan tag omitempty sangat membantu untuk mengontrol tampilan data JSON yang dihasilkan dari struct Go, terutama untuk field yang bersifat opsional. Dengan demikian, data JSON yang dihasilkan menjadi lebih ringkas dan sesuai kebutuhan aplikasi.