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

ไฮไลท์บอลโลก 2026: มหากาพย์ 48 ทีม เปิดฉากความตื่นเต้นที่คุณไม่ควรพลาด!

ไฮไลท์บอลโลก 2026: มหากาพย์ 48 ทีม เปิดฉากความตื่นเต้นที่คุณไม่ควรพลาด!

เกาะติดไฮไลท์บอลโลก 2026 ตั้งแต่นัดเปิดสนาม! สรุปผลการแข่งขันสุดเซอร์ไพรส์, ช่องทางดูบอลสดในไทยทั้งฟรีและพรีเมียม, โปรแกรมสำคัญ และทุกสิ่งที่ควรรู้.

By ทีมงาน devdog
ตารางคะแนนบอลโลก: ทุกแต้มมีความหมาย และปาฏิหาริย์ที่สั่นสะเทือนบัลลังก์

ตารางคะแนนบอลโลก: ทุกแต้มมีความหมาย และปาฏิหาริย์ที่สั่นสะเทือนบัลลังก์

เจาะลึกความสำคัญของตารางคะแนนบอลโลก พร้อมเรื่องราวสุดประทับใจของโวซินญา ผู้รักษาประตูเคปเวิร์ดที่สร้างปาฏิหาริย์หยุดสเปนในฟุตบอลโลก 2026.

By ทีมงาน devdog
ประธานเจ้าหน้าที่ฝ่ายกฎหมาย Take-Two ขายหุ้นมูลค่า 950,515 ดอลลาร์: สัญญาณอะไรที่นักลงทุนควรรู้?

ประธานเจ้าหน้าที่ฝ่ายกฎหมาย Take-Two ขายหุ้นมูลค่า 950,515 ดอลลาร์: สัญญาณอะไรที่นักลงทุนควรรู้?

ประธานเจ้าหน้าที่ฝ่ายกฎหมาย Take-Two ขายหุ้นเกือบ $1 ล้าน ท่ามกลางข่าวดี GTA 6 และรายได้คาดการณ์ $8 พันล้าน นักลงทุนควรรู้อะไร?

By ทีมงาน devdog