JSON sang Go Struct

Tạo Go struct từ JSON

Thử ví dụ
Tên struct gốc:

Đầu vào JSON

Đầu ra Go

Chạy cục bộ · An toàn để dán thông tin bí mật
Các Go struct sẽ hiển thị ở đây…

Chuyển đổi JSON sang Go là gì?

Chuyển đổi JSON sang Go biến dữ liệu JSON thô thành các định nghĩa kiểu Go hoạt động với package encoding/json trong thư viện chuẩn của Go. Go là ngôn ngữ kiểu tĩnh, vì vậy mỗi trường JSON cần một trường struct tương ứng với kiểu đúng và một struct tag để nói cho bộ tuần tự hóa biết cần ánh xạ khóa JSON nào. Việc viết tay các định nghĩa này cho các phản hồi API lớn hoặc lồng nhau sâu rất chậm và dễ mắc lỗi.

Package encoding/json, được định nghĩa trong đặc tả Go từ Go 1.0, sử dụng reflection để khớp các khóa JSON với các trường struct được xuất. Việc khớp mặc định không phân biệt chữ hoa chữ thường, nhưng việc dùng json struct tag tường minh là thông lệ chuẩn vì nó loại bỏ sự mơ hồ và cho phép bạn dùng quy ước PascalCase của Go trong khi JSON vẫn ở dạng camelCase hoặc snake_case. Một bộ chuyển đổi tự động hóa điều này: nó đọc JSON của bạn, suy luận kiểu Go từ các giá trị và xuất ra định nghĩa struct với các tag đúng.

Hệ thống kiểu của Go ánh xạ gọn gàng sang JSON. Chuỗi trở thành string, boolean trở thành bool, số nguyên trở thành int, và số thực dấu phẩy động trở thành float64. Các đối tượng JSON lồng nhau trở thành các struct có tên riêng biệt, còn mảng trở thành slice. Điểm khác biệt duy nhất là null: Go không có kiểu nullable chung, nên các giá trị null thường trở thành kiểu con trỏ (*string, *int) hoặc interface{}. Một bộ tạo xử lý tất cả điều này trong vài mili giây.

Tại sao dùng bộ chuyển đổi JSON sang Go?

Định nghĩa Go struct từ JSON bằng tay nghĩa là đếm dấu ngoặc nhọn, đoán kiểu và viết lại tag mỗi khi API thay đổi. Một bộ chuyển đổi loại bỏ sự phiền toái đó.

Tạo kiểu tức thì
Dán JSON của bạn và nhận định nghĩa Go struct đúng trong dưới một giây. Không cần gõ tay từng trường, không bỏ sót tag, không đau đầu với căn chỉnh.
🔒
Xử lý ưu tiên quyền riêng tư
Quá trình chuyển đổi chạy hoàn toàn trong trình duyệt. JSON của bạn không bao giờ rời khỏi máy. Các khóa API, token và dữ liệu người dùng luôn được bảo mật.
🏷️
Struct tag đúng chuẩn
Mỗi trường được tạo đều có json struct tag ánh xạ tên trường Go sang khóa JSON gốc. Điều này ngăn các sự không khớp âm thầm trong quá trình json.Unmarshal.
📦
Không cài đặt hay đăng ký
Mở trang và dán JSON của bạn. Không cần Go toolchain, không cần cài CLI, không cần tạo tài khoản.

Các trường hợp sử dụng JSON sang Go

Phát triển REST API Client
Tạo struct yêu cầu và phản hồi cho các REST API của bên thứ ba. Dán JSON mẫu từ tài liệu API và nhận các kiểu sẵn sàng dùng với http.Client và json.NewDecoder.
Mô hình gRPC Gateway
Khi một dịch vụ Go cung cấp cả endpoint gRPC lẫn REST, bạn cần Go struct khớp với JSON payload. Chuyển đổi cấu trúc JSON thành struct khớp với các định nghĩa protobuf của bạn.
Phân tích cấu hình DevOps
Phân tích tệp cấu hình JSON (đầu ra Terraform, manifest Kubernetes, cấu hình pipeline CI/CD) thành Go struct có kiểu cho các công cụ tùy chỉnh và script tự động hóa.
Xử lý Data Pipeline
Xây dựng Go struct cho các bản ghi JSON từ hàng đợi tin nhắn (Kafka, RabbitMQ, SQS) hoặc data lake. Struct có kiểu phát hiện thay đổi schema tại thời điểm biên dịch thay vì runtime.
Thiết lập Test Fixture
Chuyển đổi JSON test fixture thành Go struct cho các bài kiểm thử dạng bảng. Fixture an toàn về kiểu giúp chẩn đoán lỗi kiểm thử dễ hơn so với các assertion map[string]interface{} thô.
Học hệ thống kiểu của Go
Sinh viên và lập trình viên từ các ngôn ngữ động có thể dán JSON quen thuộc và xem Go biểu diễn cùng dữ liệu đó như thế nào với kiểu tường minh, con trỏ và struct tag.

Ánh xạ kiểu từ JSON sang Go

Package encoding/json tuân theo các quy tắc cụ thể khi ánh xạ giá trị JSON sang kiểu Go. Bảng dưới đây cho thấy ánh xạ mặc định và các lựa chọn thay thế phổ biến. Cột "Mặc định" là những gì hầu hết các bộ tạo xuất ra. Cột "Thay thế" cho thấy các kiểu bạn có thể chọn dựa trên yêu cầu, chẳng hạn int64 cho các ID lớn hoặc kiểu con trỏ cho các trường nullable.

Kiểu JSONVí dụMặc địnhThay thế
string"hello"stringstring
number (integer)42intint64
number (float)3.14float64float64
booleantrueboolbool
nullnullinterface{}*string / *int
object{"k": "v"}structstruct
array of strings["a", "b"][]string[]string
array of objects[{"id": 1}][]Item[]Item
mixed array[1, "a"][]interface{}[]interface{}

Tham khảo Go JSON Struct Tag

Struct tag kiểm soát cách encoding/json tuần tự hóa và giải tuần tự hóa các trường. Tag json là tag phổ biến nhất, nhưng bạn có thể kết hợp nó với các tag khác (db, yaml, xml) trên cùng một trường. Cú pháp tag là một chuỗi được giới hạn bằng dấu backtick sau kiểu trường. Dưới đây là các tùy chọn json tag mà encoding/json hỗ trợ.

TagHành viTrường hợp sử dụng
json:"name"Maps struct field to JSON key "name"Always generated
json:"name,omitempty"Omits field from output if zero valueOptional fields
json:"-"Field is never serialized or deserializedInternal fields
json:"name,string"Encodes int/bool as JSON stringString-encoded numbers

json.Unmarshal so với json.NewDecoder

Go cung cấp hai cách giải mã JSON: json.Unmarshal cho slice byte và json.NewDecoder cho luồng io.Reader. Cả hai đều dùng cùng quy tắc struct tag, nhưng khác nhau ở chỗ nên dùng khi nào.

json.Unmarshal
Nhận một []byte và điền vào struct. Phù hợp nhất cho JSON đã có đầy đủ trong bộ nhớ: nội dung phản hồi HTTP đọc bằng io.ReadAll, nội dung tệp hoặc test fixture. Trả về lỗi nếu JSON không hợp lệ hoặc kiểu không khớp.
json.NewDecoder
Bao bọc một io.Reader và giải mã token JSON khi chúng đến. Phù hợp nhất cho các nguồn luồng: nội dung phản hồi HTTP đọc trực tiếp, log JSON phân tách bằng dòng mới (NDJSON) hoặc các tệp lớn mà bạn không muốn tải toàn bộ vào bộ nhớ. Gọi Decode() trong vòng lặp với More() cho luồng nhiều đối tượng.

Ví dụ mã

Các ví dụ này cho thấy cách sử dụng Go struct được tạo từ JSON trong các chương trình thực tế, cùng cách tạo chúng từ các ngôn ngữ khác. Các ví dụ Go sử dụng encoding/json từ thư viện chuẩn.

Go (json.Unmarshal)
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]
}
JavaScript (fetch + type reference)
// 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"`
// }
Python (generate Go structs from JSON)
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"`
# }
Go (json.Decoder for streams)
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
}

Câu hỏi thường gặp

Sự khác biệt giữa json.Unmarshal và json.Decode là gì?
json.Unmarshal nhận một []byte chứa toàn bộ tài liệu JSON và điền vào struct. json.NewDecoder bao bọc một io.Reader và giải mã JSON theo từng phần. Dùng Unmarshal khi bạn đã có đầy đủ JSON trong bộ nhớ (ví dụ: sau io.ReadAll). Dùng NewDecoder khi đọc trực tiếp từ nội dung phản hồi HTTP, tệp hoặc bất kỳ nguồn luồng nào mà bạn muốn tránh lưu toàn bộ payload vào bộ đệm.
Go xử lý các trường JSON bị thiếu trong payload như thế nào?
Các trường JSON bị thiếu để lại trường struct Go tương ứng ở giá trị không (zero value): "" cho chuỗi, 0 cho số, false cho bool, nil cho con trỏ và slice. Nếu bạn cần phân biệt "trường thiếu" và "trường có mặt nhưng bằng không", hãy dùng kiểu con trỏ như *int hoặc *string. Con trỏ nil nghĩa là trường vắng mặt; con trỏ không nil với giá trị không nghĩa là nó được đặt tường minh thành 0 hoặc "".
Tại sao các trường struct Go cần được xuất (viết hoa) cho JSON?
Package encoding/json dùng reflection để truy cập các trường struct, và quy tắc reflection của Go chỉ cho phép truy cập các trường được xuất (viết hoa). Nếu một trường bắt đầu bằng chữ thường, encoding/json không thể nhìn thấy nó và sẽ âm thầm bỏ qua trong cả quá trình marshal lẫn unmarshal. Dùng json struct tag để ánh xạ trường PascalCase được xuất sang khóa JSON chữ thường.
Làm thế nào để xử lý các khóa JSON kiểu snake_case trong Go?
Thêm json struct tag với tên khóa JSON chính xác. Ví dụ: trường JSON "user_name" ánh xạ sang trường Go UserName với tag `json:"user_name"`. Bộ tạo tự động xử lý điều này. Không có tùy chọn toàn cục nào trong encoding/json để đặt chính sách đặt tên; mỗi trường phải khai báo tag riêng của mình.
Tôi có thể chuyển đổi JSON có giá trị null sang Go không?
Có. Giá trị JSON null ánh xạ sang kiểu con trỏ trong Go. Một trường như "age": null trở thành Age *int `json:"age"`. Khi giá trị JSON là null, con trỏ Go là nil. Khi có giá trị, Go cấp phát một int và con trỏ tham chiếu đến nó. Đối với các trường luôn nullable, dùng con trỏ là cách tiếp cận thông thường trong Go.
Điều gì xảy ra nếu JSON chứa số lớn hơn kiểu int của Go?
Kiểu int của Go phụ thuộc vào nền tảng (32-bit trên hệ thống 32-bit, 64-bit trên hệ thống 64-bit). Đối với các số lớn như timestamp JavaScript hoặc ID cơ sở dữ liệu, hãy dùng int64 một cách tường minh. Nếu số JSON có phần thập phân, dùng float64. Đối với các số vượt quá độ chính xác của float64 (ví dụ: các giá trị tài chính lớn), dùng json.Number, vốn giữ nguyên biểu diễn chuỗi thô và cho phép bạn tự phân tích.
Có sự khác biệt giữa công cụ này và JSON-to-Go-Struct không?
Công cụ này tạo định nghĩa kiểu Go với trọng tâm vào các mẫu sử dụng encoding/json: struct tag đúng, suy luận kiểu phù hợp và xử lý cấu trúc lồng nhau cùng mảng. Công cụ JSON sang Go Struct trên trang này tập trung vào việc tạo khung struct. Cả hai đều tạo ra mã Go hợp lệ. Dùng công cụ nào phù hợp với quy trình làm việc của bạn. Bảng tham khảo struct tag và bảng ánh xạ kiểu trên trang này hữu ích bất kể bạn chọn bộ tạo nào.