Lompati ke konten utama
Modul 8 · Pelajaran 5 dari 540/50 dalam kursus~14 min
Pelajaran modul (5/5)

`pengkodean/json`

encoding/json adalah paket kanonik untuk membuat serialisasi struct Go ke JSON dan sebaliknya. Mengetahui konvensi dan kendalanya akan menghemat waktu berjam-jam untuk melakukan debug pada API dan file konfigurasi.

Marsekal dan Unmarshal

Dua fungsi utama:

Go
data, err := json.Marshal(v)      // Go → []byte JSON
err = json.Unmarshal(data, &v)    // JSON → Go (pass a pointer!)
Go
type User struct {
    Name  string
    Email string
}

u := User{Name: "Ada", Email: "ada@example.com"}
b, _ := json.Marshal(u)
fmt.Println(string(b))
// {"Name":"Ada","Email":"ada@example.com"}

var back User
_ = json.Unmarshal(b, &back)

Untuk keluaran yang menjorok ke dalam (dapat dibaca manusia) gunakan json.MarshalIndent(v, "", " ").

Hanya bidang yang diekspor

json.Marshal membuat serial hanya kolom yang diekspor (Huruf Besar). Bidang pribadi diabaikan secara diam-diam:

Go
type U struct {
    Name string // exported → serialized
    age  int    // private → ignored
}

Tag struktur: mengontrol nama dan opsi

Tag json:"..." mengontrol nama, penghilangan, dan tipe dalam output:

Go
type User struct {
    Name    string `json:"name"`                    // rename
    Email   string `json:"email,omitempty"`         // omit if zero value
    Private string `json:"-"`                       // never serialized
    ID      int    `json:"id,string"`               // number as string
}

Opsi yang paling sering digunakan:

  • ,omitempty — menghilangkan kolom jika nilai nol (0, "", nil, irisan/peta kosong).
  • ,- — tidak pernah diserialkan/dideserialisasi.
  • ,string — membungkus angka/bool sebagai string (berguna untuk ID JS).

Decoder/Encoder untuk streaming

Saat bekerja dengan io.Reader/io.Writer (badan HTTP, file besar) gunakan Decoder dan Encoder alih-alih memuat semua yang ada di memori:

Go
dec := json.NewDecoder(resp.Body)
var users []User
if err := dec.Decode(&users); err != nil {
    return err
}

enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", "  ")
_ = enc.Encode(users)

Decoder juga mendukung dec.Token() untuk penguraian streaming sepotong demi sepotong dan dec.DisallowUnknownFields() untuk menolak JSON dengan kunci yang tidak terduga (berguna untuk validasi input).

Peta umum dan any

Jika Anda tidak mengetahui skemanya, deserialisasikan ke map[string]any:

Go
var v map[string]any
_ = json.Unmarshal(data, &v)
fmt.Println(v["name"])

Nilai akan memiliki tipe dinamis (string, float64 untuk angka, []any, map[string]any, bool, nil).

Kesalahan umum

  • Lupa &: json.Unmarshal(data, v) tidak mengisi apa pun; Anda membutuhkan &v.
  • Mendekode struct dengan kolom nihil: untuk menghindari kepanikan, periksa err SEBELUM membaca kolom.
  • Jenis yang tidak kompatibel: membatalkan serialisasi angka menjadi string atau sebaliknya akan mengembalikan *json.UnmarshalTypeError.

Latihan

Latihan#go.m8.l5.e1
Upaya: 0Memuat…

Buat serial struct u ke JSON dengan json.Marshal dan cetak hasilnya sebagai string.

Memuat editor…

Solusi tersedia setelah 3 upaya

Latihan#go.m8.l5.e2
Upaya: 0Memuat…

Deserialisasi `{"Name":"Ada"}` ke dalam struct U dengan json.Unmarshal dan cetak.

Memuat editor…

Solusi tersedia setelah 3 upaya

Quiz#go.m8.l5.e3
Siap

Apakah bidang `string nama` (huruf kecil) dari suatu struct disertakan oleh json.Marshal?

Go
type U struct {
  name string
}
b, _ := json.Marshal(U{name: "Ada"})
fmt.Println(string(b))
Pilihan jawaban