JSON to Go Struct
Hasilkan Go struct dari JSON
Input JSON
Output Go
Apa itu Konversi JSON ke Go Struct?
Konversi JSON ke Go mengubah data JSON mentah menjadi definisi tipe Go yang bekerja dengan paket encoding/json dari pustaka standar Go. Go adalah bahasa bertipe statis, sehingga setiap field JSON memerlukan field struct yang sesuai dengan tipe yang benar dan struct tag yang memberi tahu serializer kunci JSON mana yang dipetakan. Menulis definisi-definisi ini secara manual untuk respons API yang besar atau sangat bersarang itu lambat dan mudah keliru.
Paket encoding/json, yang telah ada dalam spesifikasi Go sejak Go 1.0, menggunakan reflection untuk mencocokkan kunci JSON dengan field struct yang diekspor. Pencocokan bersifat case-insensitive secara default, tetapi struct tag json yang eksplisit adalah praktik standar karena menghilangkan ambiguitas dan memungkinkan penggunaan konvensi PascalCase Go sementara JSON tetap dalam camelCase atau snake_case. Sebuah konverter mengotomatiskan ini: ia membaca JSON Anda, menyimpulkan tipe Go dari nilai-nilainya, dan menghasilkan definisi struct dengan tag yang benar.
Sistem tipe Go memetakan JSON dengan bersih. String menjadi string, boolean menjadi bool, integer menjadi int, dan angka floating-point menjadi float64. Objek JSON bersarang menjadi struct bernama terpisah, dan array menjadi slice. Satu celah adalah null: Go tidak memiliki tipe nullable universal, sehingga nilai null biasanya menjadi tipe pointer (*string, *int) atau interface{}. Sebuah generator menangani semua ini dalam hitungan milidetik.
Mengapa Menggunakan Konverter JSON ke Go?
Mendefinisikan Go struct dari JSON secara manual berarti menghitung kurung kurawal, menebak tipe, dan menulis ulang tag setiap kali API berubah. Sebuah konverter menghilangkan gesekan tersebut.
Kasus Penggunaan JSON ke Go Struct
Pemetaan Tipe JSON ke Go
Paket encoding/json mengikuti aturan tertentu saat memetakan nilai JSON ke tipe Go. Tabel di bawah menunjukkan pemetaan default dan alternatif yang umum. Kolom "Default" adalah yang dihasilkan oleh sebagian besar generator. Kolom "Alternatif" menampilkan tipe yang mungkin Anda pilih berdasarkan kebutuhan, seperti int64 untuk ID besar atau tipe pointer untuk field nullable.
| Tipe JSON | Contoh | Default | Alternatif |
|---|---|---|---|
| string | "hello" | string | string |
| number (integer) | 42 | int | int64 |
| number (float) | 3.14 | float64 | float64 |
| boolean | true | bool | bool |
| null | null | interface{} | *string / *int |
| object | {"k": "v"} | struct | struct |
| array of strings | ["a", "b"] | []string | []string |
| array of objects | [{"id": 1}] | []Item | []Item |
| mixed array | [1, "a"] | []interface{} | []interface{} |
Referensi Struct Tag JSON di Go
Struct tag mengontrol cara encoding/json melakukan serialisasi dan deserialisasi field. Tag json adalah yang paling umum digunakan, tetapi Anda dapat menggabungkannya dengan tag lain (db, yaml, xml) pada field yang sama. Sintaks tag adalah string yang dibatasi backtick setelah tipe field. Berikut adalah opsi tag json yang didukung encoding/json.
| Tag | Perilaku | Kasus Penggunaan |
|---|---|---|
| json:"name" | Maps struct field to JSON key "name" | Always generated |
| json:"name,omitempty" | Omits field from output if zero value | Optional fields |
| json:"-" | Field is never serialized or deserialized | Internal fields |
| json:"name,string" | Encodes int/bool as JSON string | String-encoded numbers |
json.Unmarshal vs json.NewDecoder
Go menyediakan dua cara untuk mendekode JSON: json.Unmarshal untuk slice byte dan json.NewDecoder untuk stream io.Reader. Keduanya menggunakan aturan struct tag yang sama, tetapi berbeda dalam kapan harus digunakan.
Contoh Kode
Contoh-contoh ini menunjukkan cara menggunakan Go struct yang dihasilkan dari JSON dalam program nyata, beserta cara menghasilkannya dari bahasa lain. Contoh Go menggunakan encoding/json dari pustaka standar.
package main
import (
"encoding/json"
"fmt"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
IsActive bool `json:"is_active"`
Tags []string `json:"tags"`
}
func main() {
data := []byte(`{"id":1,"name":"Alice","email":"alice@example.com","is_active":true,"tags":["admin","editor"]}`)
var user User
if err := json.Unmarshal(data, &user); err != nil {
panic(err)
}
fmt.Println(user.Name) // โ Alice
fmt.Println(user.Tags) // โ [admin editor]
}// JSON response from API โ this is the shape you'd convert to Go:
const res = await fetch("https://api.example.com/users/1");
const user = await res.json();
// user โ { "id": 1, "name": "Alice", "email": "alice@example.com" }
// Equivalent Go struct:
// type User struct {
// ID int `json:"id"`
// Name string `json:"name"`
// Email string `json:"email"`
// }import json
def json_to_go(data: dict, name: str = "Root") -> str:
lines = [f"type {name} struct {{"]
type_map = {str: "string", int: "int", float: "float64", bool: "bool"}
for key, value in data.items():
go_type = type_map.get(type(value), "interface{}")
field = key.title().replace("_", "") # snake_case โ PascalCase
lines.append(f'\t{field} {go_type} `json:"{key}"`')
lines.append("}")
return "\n".join(lines)
data = json.loads('{"user_name": "Alice", "age": 30, "verified": true}')
print(json_to_go(data))
# type Root struct {
# UserName string `json:"user_name"`
# Age int `json:"age"`
# Verified bool `json:"verified"`
# }package main
import (
"encoding/json"
"fmt"
"strings"
)
type Event struct {
Type string `json:"type"`
Payload string `json:"payload"`
}
func main() {
stream := strings.NewReader(`{"type":"click","payload":"btn-1"}
{"type":"scroll","payload":"page-2"}`)
dec := json.NewDecoder(stream)
for dec.More() {
var ev Event
if err := dec.Decode(&ev); err != nil {
break
}
fmt.Printf("%s: %s\n", ev.Type, ev.Payload)
}
// โ click: btn-1
// โ scroll: page-2
}