Go มันก็แปลง JSON ง่ายนิดเดียว! (ถ้าไม่เผลอพลาด)

สวัสดีครับ! วันนี้ผมอยากเล่าเรื่องการทำงานกับ JSON ใน Go (Golang) ให้ฟัง. แรกๆ ที่ผมเริ่มเขียน Go เนี่ย ยอมรับเลยว่าแอบ งง นิดๆ กับเรื่อง struct กับ tag ว่ามันจะแปลงเป็น JSON ได้ไงฟะ? แต่พอเข้าใจคอนเซ็ปต์แล้วมันก็โคตร ง่ายเลยนะ

พื้นฐานก่อน Go เนี่ย มันมี encoding/json มาให้ในตัวเลย ไม่ต้อง ลง package เพิ่มให้วุ่นวาย. เวลาเราจะแปลง struct เป็น JSON (Marshal) หรือแปลง JSON กลับมาเป็น struct (Unmarshal) เนี่ย มันใช้สองฟังก์ชันนี้แหละ

สมมติเรามี struct ง่ายๆ แบบนี้:

package main

import "fmt"
import "encoding/json"

type User struct {
    ID        int    `json:"id"`
    Name      string `json:"name"`
    Email     string `json:"email,omitempty"` // omitempty คือถ้าค่าว่าง (zero value) จะไม่เอาเข้า JSON
    IsActive  bool   `json:"is_active"`
    CreatedAt string `json:"created_at"`
}

func main() {
    // สร้าง User object
    u := User{
        ID:        1,
        Name:      "บักหำน้อย",
        Email:     "[email protected]",
        IsActive:  true,
        CreatedAt: "2023-10-27T10:00:00Z",
    }

    // Marshal (แปลง struct เป็น JSON)
    jsonData, err := json.Marshal(u)
    if err != nil {
        fmt.Println("Error marshalling JSON:", err)
        return
    }
    fmt.Println("JSON จาก Struct:")
    fmt.Println(string(jsonData))

    fmt.Println("\n---")

    // Unmarshal (แปลง JSON กลับมาเป็น struct)
    jsonString := `{"id":2,"name":"เจ๊แต๋ว","email":"[email protected]","is_active":false,"created_at":"2023-10-27T11:00:00Z"}`
    var newUser User
    err = json.Unmarshal([]byte(jsonString), &newUser)
    if err != nil {
        fmt.Println("Error unmarshalling JSON:", err)
        return
    }
    fmt.Println("Struct จาก JSON:")
    fmt.Printf("ID: %d, Name: %s, Email: %s, IsActive: %t\n", newUser.ID, newUser.Name, newUser.Email, newUser.IsActive)

}

รันโค้ดบนจะเห็นผลลัพธ์ประมาณนี้:

JSON จาก Struct:
{"id":1,"name":"บักหำน้อย","email":"[email protected]","is_active":true,"created_at":"2023-10-27T10:00:00Z"}

---
Struct จาก JSON:
ID: 2, Name: เจ๊แต๋ว, Email: [email protected], IsActive: false

สิ่งที่ผมเคยเจอตอนทำโปรเจกต์ (Error เล็กๆ แต่โคตรน่าหงุดหงิด) อันนี้จริงๆ มันไม่ใช่ Error แบบโปรแกรมพัง แต่มันคือ "Data ไม่มาตามที่คิด" นั่นแหละ สมมติคุณได้รับ JSON มาแบบนี้ (จาก API ปลายทางอะไรก็ได้):

{
  "userId": 123,
  "userName": "Boss",
  "isActive": "true"  <-- ตรงนี้แหละตัวดี
}

แล้วเราดันไปประกาศ struct แบบนี้:

type APIResponse struct {
    UserID   int    `json:"userId"`
    UserName string `json:"userName"`
    IsActive bool   `json:"isActive"` // หวังว่าจะได้ bool ใช่ไหม?
}

พอคุณเอาไป json.Unmarshal ปุ๊บ โอกาสที่คุณจะเจอ false ใน IsActive ทั้งที่ใน JSON มันเป็น "true" สูงมาก หรือบางทีก็ Error ไปเลย เพราะ Go มันคาดหวัง bool (true/false) จริงๆ ไม่ใช่ string "true"/"false"

ตัวอย่าง Error ที่เจอ: ถ้าเราลองทำแบบนี้

package main

import (
    "encoding/json"
    "fmt"
)

type BadUser struct {
    ID        int    `json:"id"`
    IsActive  bool   `json:"is_active"`
}

func main() {
    badJsonString := `{"id":1,"is_active":"true"}` // is_active เป็น string แทนที่จะเป็น bool
    var badUser BadUser
    err := json.Unmarshal([]byte(badJsonString), &badUser)
    if err != nil {
        fmt.Println("เฮ้ย! เกิด Error ตอน Unmarshal:", err)
        // Error ที่เจอจริงจะประมาณนี้:
        // เฮ้ย! เกิด Error ตอน Unmarshal: json: cannot unmarshal string into Go struct field BadUser.is_active of type bool
        return
    }
    fmt.Printf("BadUser: %+v\n", badUser)
}

เห็นไหม! มันจะฟ้องเลยว่า "cannot unmarshal string into Go struct field ... of type bool" วิธีแก้ก็คือ ต้องไปดู type ใน JSON ที่ได้รับมาดีๆ ว่ามันเป็น string หรือ bool หรือ int กันแน่. ถ้ามันไม่ตรง ก็ต้องปรับ struct เราให้ตรง หรือ ไม่ก็ต้องเขียน Custom Unmarshaler ซึ่งอันนั้นมันจะแอดวานซ์ไปหน่อย. สำหรับมือใหม่แค่รู้ว่ามันเกิดแบบนี้ได้ก็พอละ

สรุปแล้ว การจัดการ JSON ใน Go ไม่ได้ยากอย่างที่คิด แค่ต้องระวังเรื่อง type mismatch ให้ดีๆ ครับ. ถ้าติดตรงไหนลองพิมพ์ดู error ที่เจอแล้ว Search Google ดู ส่วนใหญ่จะมีคนเจอเหมือนๆ กันเยอะแยะ! โชคดีครับ!

Read more

ไอลีน กู: ตำนานนักสกีฟรีสไตล์ผู้พลิกโฉมวงการและความหมายของชัยชนะ

ไอลีน กู: ตำนานนักสกีฟรีสไตล์ผู้พลิกโฉมวงการและความหมายของชัยชนะ

เจาะลึกเรื่องราวของ Eileen Gu นักสกีฟรีสไตล์ผู้สร้างประวัติศาสตร์ในโอลิมปิก 2026 สถิติที่ไม่เคยมีมาก่อน ประเด็นถกเถียง และความแข็งแกร่งส่วนตัวที่ทำให้เธอก้าวสู่ระดับโลก

By ทีมงาน devdog
วันพระ: คู่มือฉบับสมบูรณ์สำหรับพุทธศาสนิกชนและผู้สนใจยุคใหม่

วันพระ: คู่มือฉบับสมบูรณ์สำหรับพุทธศาสนิกชนและผู้สนใจยุคใหม่

เจาะลึกวันพระและความสำคัญของวันมาฆบูชา 2569 ทั้งวันหยุดราชการ ธนาคาร กิจกรรมเวียนเทียนต้นไม้ และผลกระทบต่อบริการขนส่ง เตรียมตัววางแผนทำบุญและพักผ่อน

By ทีมงาน devdog
ถอดรหัสรักแท้: "บังมัดคลองตันต้นข้าว" เรื่องราวที่สะท้อนการให้อภัยและการเริ่มต้นใหม่

ถอดรหัสรักแท้: "บังมัดคลองตันต้นข้าว" เรื่องราวที่สะท้อนการให้อภัยและการเริ่มต้นใหม่

เจาะลึกงานวิวาห์ "บังมัดคลองตัน" กับ "ต้นข้าว มิสแกรนด์" พร้อมเหตุผลจากใจเจ้าสาวที่เลือกความรักเหนือกาลเวลาและคำวิจารณ์ สู่การเริ่มต้นชีวิตคู่ที่สะท้อนการให้อภัย

By ทีมงาน devdog
ไฮไลท์บอลไทยลีก 2: มหาสารคาม เอสบีที เอฟซี กับฟอร์มร้อนแรงสู่เส้นทางเพลย์ออฟ

ไฮไลท์บอลไทยลีก 2: มหาสารคาม เอสบีที เอฟซี กับฟอร์มร้อนแรงสู่เส้นทางเพลย์ออฟ

เจาะลึกไฮไลท์บอลไทยลีก 2 ของมหาสารคาม เอสบีที เอฟซี กับฟอร์มร้อนแรง ชัยชนะสำคัญจาก ชิตชนก และบทบาทโค้ชดุสิต สู่เส้นทางเพลย์ออฟที่น่าจับตา!

By ทีมงาน devdog