ToolDeck

JSON به ساختار Go

تولید struct های Go از JSON

یک مثال امتحان کنید
نام struct اصلی:

ورودی JSON

خروجی Go

به‌صورت محلی اجرا می‌شود · جای‌گذاری اسرار امن است
struct های Go اینجا نمایش داده می‌شوند…

تبدیل JSON به ساختار Go چیست؟

تبدیل JSON به Go داده‌های JSON خام را به تعریف نوع‌های Go تبدیل می‌کند که با پکیج encoding/json در کتابخانه استاندارد Go کار می‌کنند. Go یک زبان با نوع‌بندی ایستا است، بنابراین هر فیلد JSON به یک فیلد struct متناظر با نوع صحیح و یک struct tag نیاز دارد که به serializer بگوید کدام کلید JSON را نگاشت کند. نوشتن این تعریف‌ها به‌صورت دستی برای پاسخ‌های API بزرگ یا عمیقاً تودرتو وقت‌گیر و مستعد خطاست.

پکیج encoding/json که از Go 1.0 در مشخصات زبان تعریف شده، از reflection برای نگاشت کلیدهای JSON به فیلدهای struct صادرشده استفاده می‌کند. این نگاشت به‌صورت پیش‌فرض case-insensitive است، اما استفاده صریح از json struct tag روش استاندارد است زیرا ابهام را از بین می‌برد و به شما اجازه می‌دهد قرارداد PascalCase در Go را حفظ کنید در حالی که JSON همچنان به صورت camelCase یا snake_case باقی می‌ماند. یک مبدل این فرایند را خودکار می‌کند: JSON شما را می‌خواند، نوع‌های Go را از مقادیر استنتاج می‌کند، و تعریف struct با tag های صحیح را تولید می‌کند.

سیستم نوع Go به‌خوبی به JSON نگاشت می‌شود. رشته‌ها به string، مقادیر boolean به bool، اعداد صحیح به int، و اعداد اعشاری به float64 تبدیل می‌شوند. اشیاء JSON تودرتو به struct های جداگانه با نام مخصوص تبدیل می‌شوند، و آرایه‌ها به slice تبدیل می‌شوند. یک استثنا وجود دارد: null — Go هیچ نوع nullable جهانی ندارد، بنابراین مقادیر null معمولاً به نوع‌های pointer (*string، *int) یا interface{} تبدیل می‌شوند. یک مولد همه این‌ها را در چند میلی‌ثانیه مدیریت می‌کند.

چرا از مبدل JSON به Go استفاده کنیم؟

تعریف دستی struct های Go از JSON به معنای شمارش آکولادها، حدس زدن نوع‌ها، و بازنویسی tag ها با هر بار تغییر API است. یک مبدل از این دردسر جلوگیری می‌کند.

تولید فوری نوع‌ها
JSON را جایگذاری کنید و تعریف‌های صحیح struct Go را در کمتر از یک ثانیه دریافت کنید. بدون نوشتن دستی فیلدها، بدون فراموش کردن tag، بدون دردسر تراز کردن.
🔒
پردازش با اولویت حریم خصوصی
تبدیل کاملاً در مرورگر شما انجام می‌شود. JSON شما هرگز دستگاهتان را ترک نمی‌کند. کلیدهای API، توکن‌ها و داده‌های کاربران خصوصی می‌مانند.
🏷️
struct tag های صحیح
هر فیلد تولیدشده شامل یک json struct tag است که نام فیلد Go را به کلید JSON اصلی نگاشت می‌کند. این از خطاهای پنهان در طول json.Unmarshal جلوگیری می‌کند.
📦
بدون نصب یا ثبت‌نام
صفحه را باز کنید و JSON را جایگذاری کنید. نیازی به زنجیره ابزار Go، ابزارهای CLI برای نصب، یا حساب کاربری برای ایجاد نیست.

موارد استفاده JSON به ساختار Go

توسعه Client برای REST API
struct های درخواست و پاسخ برای REST API های شخص ثالث تولید کنید. نمونه JSON از مستندات API را جایگذاری کنید و نوع‌های آماده برای http.Client و json.NewDecoder دریافت کنید.
مدل‌های Gateway در gRPC
وقتی یک سرویس Go هم endpoint های gRPC و هم REST را ارائه می‌دهد، به struct های Go نیاز دارید که با payload های JSON مطابقت داشته باشند. شکل JSON را به struct هایی تبدیل کنید که با تعریف‌های protobuf شما مطابقت داشته باشند.
پردازش پیکربندی در DevOps
فایل‌های پیکربندی JSON (خروجی Terraform، مانیفست‌های Kubernetes، پیکربندی‌های خط لوله CI/CD) را به struct های Go با نوع‌بندی ایستا برای ابزار سفارشی و اسکریپت‌های اتوماسیون تبدیل کنید.
پردازش در خط لوله داده
struct های Go برای رکوردهای JSON از صف‌های پیام (Kafka، RabbitMQ، SQS) یا مخازن داده بسازید. struct های با نوع‌بندی ایستا تغییرات schema را در زمان کامپایل به‌جای زمان اجرا شناسایی می‌کنند.
راه‌اندازی fixture های تست
fixture های JSON تست را به struct های Go برای تست‌های table-driven تبدیل کنید. fixture های type-safe تشخیص شکست تست را نسبت به assertion های خام map[string]interface{} آسان‌تر می‌کنند.
یادگیری سیستم نوع Go
دانشجویان و توسعه‌دهندگانی که از زبان‌های پویا می‌آیند می‌توانند JSON آشنا را جایگذاری کنند و ببینند چگونه Go همان داده را با نوع‌های صریح، pointer ها، و struct tag ها نمایش می‌دهد.

جدول نگاشت نوع JSON به Go

پکیج encoding/json هنگام نگاشت مقادیر JSON به نوع‌های Go از قوانین خاصی پیروی می‌کند. جدول زیر نگاشت پیش‌فرض و گزینه‌های رایج جایگزین را نشان می‌دهد. ستون «پیش‌فرض» همان چیزی است که اکثر مولدها تولید می‌کنند. ستون «جایگزین» نوع‌هایی را نشان می‌دهد که ممکن است بر اساس نیازهایتان انتخاب کنید، مانند int64 برای شناسه‌های بزرگ یا نوع‌های pointer برای فیلدهای nullable.

نوع JSONمقدار نمونهپیش‌فرضجایگزین
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{}

مرجع json struct tag در Go

struct tag ها کنترل می‌کنند که encoding/json چگونه فیلدها را سریال‌سازی و deserialization می‌کند. json tag تا حد زیادی رایج‌ترین است، اما می‌توانید آن را با tag های دیگر (db، yaml، xml) روی همان فیلد ترکیب کنید. دستور زبان tag یک رشته محدودشده با backtick پس از نوع فیلد است. در اینجا گزینه‌های json tag که encoding/json پشتیبانی می‌کند آمده است.

Tagرفتارموارد استفاده
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 در مقابل json.NewDecoder

Go دو روش برای رمزگشایی JSON ارائه می‌دهد: json.Unmarshal برای slice های بایت و json.NewDecoder برای stream های io.Reader. هر دو از همان قوانین struct tag استفاده می‌کنند، اما در زمان استفاده با هم تفاوت دارند.

json.Unmarshal
یک []byte دریافت می‌کند و یک struct را پر می‌کند. بهترین گزینه برای JSON که کاملاً در حافظه است: بدنه پاسخ‌های HTTP خوانده‌شده با io.ReadAll، محتوای فایل، یا fixture های تست. در صورتی که JSON ناقص باشد یا نوع‌ها مطابقت نداشته باشند خطا برمی‌گرداند.
json.NewDecoder
یک io.Reader را می‌پوشاند و توکن‌های JSON را به محض ورود رمزگشایی می‌کند. بهترین گزینه برای منابع streaming: بدنه پاسخ‌های HTTP خوانده‌شده مستقیم، JSON با جداکننده خط جدید (NDJSON) در لاگ‌ها، یا فایل‌های بزرگی که نمی‌خواهید کاملاً در حافظه بارگذاری کنید. برای stream های چند آبجکتی Decode() را در یک حلقه با More() فراخوانی کنید.

نمونه کد

این مثال‌ها نشان می‌دهند چگونه از struct های Go تولیدشده از JSON در برنامه‌های واقعی استفاده کنید، به‌علاوه نحوه تولید آن‌ها از زبان‌های دیگر. مثال‌های Go از encoding/json در کتابخانه استاندارد استفاده می‌کنند.

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
}

سوالات متداول

تفاوت بین json.Unmarshal و json.Decode چیست؟
json.Unmarshal یک []byte حاوی سند کامل JSON دریافت می‌کند و یک struct را پر می‌کند. json.NewDecoder یک io.Reader را می‌پوشاند و JSON را به‌صورت تدریجی رمزگشایی می‌کند. از Unmarshal استفاده کنید وقتی JSON کامل را از قبل در حافظه دارید (مثلاً پس از io.ReadAll). از NewDecoder استفاده کنید وقتی مستقیماً از بدنه پاسخ HTTP، یک فایل، یا هر منبع streaming که می‌خواهید از بافر کردن کل payload اجتناب کنید می‌خوانید.
Go چگونه فیلدهای JSON که در payload وجود ندارند را مدیریت می‌کند؟
فیلدهای JSON که وجود ندارند فیلد struct متناظر Go را با مقدار zero آن باقی می‌گذارند: "" برای رشته‌ها، 0 برای اعداد، false برای bool ها، nil برای pointer ها و slice ها. اگر نیاز دارید بین «فیلد غایب» و «فیلد موجود ولی صفر» تمایز قائل شوید، از نوع pointer مانند *int یا *string استفاده کنید. یک pointer با مقدار nil به معنی غیاب فیلد است؛ یک pointer غیر-nil با مقدار صفر به معنی تنظیم صریح آن روی 0 یا "" است.
چرا فیلدهای struct Go باید صادرشده (با حرف بزرگ) باشند تا با JSON کار کنند؟
پکیج encoding/json از reflection برای دسترسی به فیلدهای struct استفاده می‌کند، و قوانین reflection در Go فقط اجازه دسترسی به فیلدهای صادرشده (با حرف بزرگ) را می‌دهند. اگر یک فیلد با حرف کوچک شروع شود، encoding/json نمی‌تواند آن را ببیند و در طول هر دو marshaling و unmarshaling بی‌سروصدا نادیده می‌گیرد. از json struct tag برای نگاشت فیلد PascalCase صادرشده به کلید JSON با حرف کوچک استفاده کنید.
چگونه کلیدهای JSON با فرمت snake_case را در Go مدیریت کنم؟
یک json struct tag با نام دقیق کلید JSON اضافه کنید. به‌عنوان مثال، فیلد JSON "user_name" به فیلد Go UserName با tag `json:"user_name"` نگاشت می‌شود. مولد این کار را به‌طور خودکار مدیریت می‌کند. هیچ گزینه سراسری در encoding/json برای تنظیم سیاست نام‌گذاری وجود ندارد؛ هر فیلد باید tag خود را اعلام کند.
آیا می‌توانم JSON با مقادیر null را به Go تبدیل کنم؟
بله. مقادیر null در JSON به نوع‌های pointer در Go نگاشت می‌شوند. فیلدی مانند "age": null به Age *int `json:"age"` تبدیل می‌شود. وقتی مقدار JSON برابر null است، pointer در Go برابر nil می‌شود. وقتی مقداری دارد، Go یک int تخصیص می‌دهد و pointer به آن اشاره می‌کند. برای فیلدهایی که همیشه nullable هستند، استفاده از pointer رویکرد اصطلاحی در Go است.
اگر JSON حاوی عددی بزرگ‌تر از int در Go باشد چه اتفاقی می‌افتد؟
int در Go به پلتفرم وابسته است (32 بیتی روی سیستم‌های 32 بیتی، 64 بیتی روی سیستم‌های 64 بیتی). برای اعداد بزرگ مانند timestamp های JavaScript یا شناسه‌های پایگاه داده، به‌صراحت از int64 استفاده کنید. اگر عدد JSON دارای اعشار باشد، از float64 استفاده کنید. برای اعدادی که از دقت float64 فراتر می‌روند (مثلاً مقادیر مالی بزرگ)، از json.Number استفاده کنید که نمایش رشته خام را نگه می‌دارد و به شما اجازه می‌دهد خودتان آن را تجزیه کنید.
آیا تفاوتی بین این ابزار و JSON-to-Go-Struct وجود دارد؟
این ابزار تعریف‌های نوع Go را با تمرکز بر الگوهای استفاده از encoding/json تولید می‌کند: struct tag های صحیح، استنتاج صحیح نوع، و مدیریت ساختارهای تودرتو و آرایه‌ها. ابزار JSON to Go Struct در این سایت بر scaffolding struct تمرکز دارد. هر دو کد Go معتبر تولید می‌کنند. از هر کدام که با جریان کار شما مطابقت دارد استفاده کنید. مرجع struct tag و جداول نگاشت نوع در این صفحه بدون توجه به اینکه از کدام مولد استفاده می‌کنید مفید هستند.