← Danh sách bài học Bài 19/20

🔗 Bài 19: JSON API

⏱️ 25 phút | 📚 Nâng cao

🎯 Mục tiêu:

1. Struct Với JSON Tags

type User struct {
    ID        int    `json:"id"`
    Name      string `json:"name"`
    Email     string `json:"email"`
    Password  string `json:"-"`           // Bỏ qua
    CreatedAt string `json:"created_at,omitempty"`
}
💡 JSON Tags:
json:"name" - đổi tên field
json:"-" - không include
json:"...,omitempty" - bỏ qua nếu empty

2. Marshal (Struct → JSON)

import "encoding/json"

user := User{
    ID:    1,
    Name:  "Minh",
    Email: "[email protected]",
}

// Convert struct → JSON bytes
jsonData, err := json.Marshal(user)
if err != nil {
    log.Fatal(err)
}

fmt.Println(string(jsonData))
// {"id":1,"name":"Minh","email":"[email protected]"}

3. Unmarshal (JSON → Struct)

jsonStr := `{"id":1,"name":"Minh","email":"[email protected]"}`

var user User
err := json.Unmarshal([]byte(jsonStr), &user)
if err != nil {
    log.Fatal(err)
}

fmt.Println(user.Name)  // Minh

4. JSON API Handler

package main

import (
    "encoding/json"
    "net/http"
)

type Response struct {
    Success bool   `json:"success"`
    Message string `json:"message"`
}

func apiHandler(w http.ResponseWriter, r *http.Request) {
    // Set Content-Type
    w.Header().Set("Content-Type", "application/json")
    
    response := Response{
        Success: true,
        Message: "Hello from API!",
    }
    
    // Encode và gửi
    json.NewEncoder(w).Encode(response)
}

func main() {
    http.HandleFunc("/api", apiHandler)
    http.ListenAndServe(":8080", nil)
}

5. Nhận JSON Request

type CreateUserRequest struct {
    Name  string `json:"name"`
    Email string `json:"email"`
}

func createUserHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != "POST" {
        http.Error(w, "Method not allowed", 405)
        return
    }
    
    var req CreateUserRequest
    
    // Decode JSON body
    err := json.NewDecoder(r.Body).Decode(&req)
    if err != nil {
        http.Error(w, "Invalid JSON", 400)
        return
    }
    
    // Xử lý...
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(map[string]string{
        "message": "Created user: " + req.Name,
    })
}

6. REST API Pattern

// GET    /users      → List users
// POST   /users      → Create user
// GET    /users/{id} → Get user by ID
// PUT    /users/{id} → Update user
// DELETE /users/{id} → Delete user

var users = []User{}

func usersHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    
    switch r.Method {
    case "GET":
        json.NewEncoder(w).Encode(users)
    case "POST":
        var user User
        json.NewDecoder(r.Body).Decode(&user)
        user.ID = len(users) + 1
        users = append(users, user)
        w.WriteHeader(http.StatusCreated)
        json.NewEncoder(w).Encode(user)
    }
}

📝 Tóm Tắt