#Fiber คืออะไร

Fiber เป็น Web Framework สำหรับภาษา Go ที่เน้นความเร็วและ API ที่เขียนกระชับ โดยสร้างบน fasthttp เหมาะกับ REST API, microservices และ backend applications ตัวอย่างนี้ใช้ Fiber v3 ซึ่งมี API บางส่วนต่างจาก Fiber v2

info-rest-api-go-fiber

#เตรียมเครื่องมือ

  • Go เวอร์ชันที่ Fiber v3 รองรับ (ตรวจสอบข้อกำหนดล่าสุดในเอกสารทางการ)
  • curl หรือ Postman
mkdir fiber-workshop && cd fiber-workshop
go mod init example.com/fiber-workshop
go get github.com/gofiber/fiber/v3

#สร้าง REST API

สร้างไฟล์ main.go:

package main

import (
    "log"
    "strconv"
    "sync"

    "github.com/gofiber/fiber/v3"
)

type Product struct {
    ID    int     `json:"id"`
    Name  string  `json:"name"`
    Price float64 `json:"price"`
}

var (
    mu = sync.RWMutex{}
    products = map[int]Product{
        1: {ID: 1, Name: "Keyboard", Price: 990},
    }
    nextID = 2
)

func main() {
    app := fiber.New()

    app.Get("/health", func(c fiber.Ctx) error {
        return c.JSON(fiber.Map{"status": "ok"})
    })

    app.Get("/api/products", func(c fiber.Ctx) error {
        mu.RLock()
        defer mu.RUnlock()
        list := make([]Product, 0, len(products))
        for _, p := range products { list = append(list, p) }
        return c.JSON(list)
    })

    app.Get("/api/products/:id", func(c fiber.Ctx) error {
        id, err := strconv.Atoi(c.Params("id"))
        if err != nil { return fiber.NewError(fiber.StatusBadRequest, "invalid id") }
        mu.RLock()
        p, ok := products[id]
        mu.RUnlock()
        if !ok { return fiber.NewError(fiber.StatusNotFound, "product not found") }
        return c.JSON(p)
    })

    app.Post("/api/products", func(c fiber.Ctx) error {
        var input Product
        if err := c.Bind().Body(&input); err != nil {
            return fiber.NewError(fiber.StatusBadRequest, "invalid JSON")
        }
        if input.Name == "" || input.Price < 0 {
            return fiber.NewError(fiber.StatusBadRequest, "name is required and price must be non-negative")
        }
        mu.Lock()
        input.ID = nextID
        nextID++
        products[input.ID] = input
        mu.Unlock()
        return c.Status(fiber.StatusCreated).JSON(input)
    })

    app.Delete("/api/products/:id", func(c fiber.Ctx) error {
        id, err := strconv.Atoi(c.Params("id"))
        if err != nil { return fiber.NewError(fiber.StatusBadRequest, "invalid id") }
        mu.Lock()
        _, ok := products[id]
        if ok { delete(products, id) }
        mu.Unlock()
        if !ok { return fiber.NewError(fiber.StatusNotFound, "product not found") }
        return c.SendStatus(fiber.StatusNoContent)
    })

    log.Fatal(app.Listen(":3000"))
}

#ทดลองใช้งาน

go run .
# อีก terminal
curl http://localhost:3000/health
curl http://localhost:3000/api/products
curl -X POST http://localhost:3000/api/products \
  -H 'Content-Type: application/json' \
  -d '{"name":"Mouse","price":450}'
curl http://localhost:3000/api/products/2
curl -i -X DELETE http://localhost:3000/api/products/2

#สรุป Endpoint

Method Path การทำงาน
GET /health ตรวจสอบสถานะ
GET /api/products แสดงสินค้าทั้งหมด
GET /api/products/:id ค้นหาสินค้า
POST /api/products เพิ่มสินค้า
DELETE /api/products/:id ลบสินค้า

#ประเด็นสำคัญสำหรับ Production

ตัวอย่างนี้เก็บข้อมูลในหน่วยความจำ จึงสูญหายเมื่อรีสตาร์ตและไม่เหมาะกับการทำงานหลาย instance ควรใช้ PostgreSQL หรือฐานข้อมูลอื่น เพิ่ม validation แบบเข้มงวด, authentication/authorization, request logging, graceful shutdown, integration tests, configuration ผ่าน environment variables และกำหนด timeout กับ reverse proxy ให้เหมาะสม นอกจากนี้ไม่ควรเผยแพร่ข้อความ error ภายในระบบให้ผู้ใช้โดยตรง

#เอกสารอ้างอิง