สร้าง Go Fiber RESTful API
หากคุณสงสัยว่าจะเริ่มต้นพัฒนา API ใน Go ได้อย่างไร หรือคุณเพิ่งเข้าใจพื้นฐานของ Go และต้องการเริ่มต้นกับการพัฒนาจริง นี่จะเป็นจุดเริ่มต้นที่ดี
Go Fiber เป็นเว็บเฟรมเวิร์กแบบ Go-based ใหม่ที่ได้รับความนิยมอย่างมากจากชุมชนการเขียนโปรแกรม พื้นที่เก็บข้อมูลสำหรับเฟรมเวิร์กอยู่ในหน้า GitHub Trending สำหรับการเขียนโปรแกรมภาษา Go อย่างสม่ำเสมอ และด้วยเหตุนี้ เราจึงต้องลองสร้าง REST API อย่างง่าย
Rest (Representational state transfer) – เป็นรูปแบบสถาปัตยกรรมซอฟต์แวร์ (architecture) ที่ใช้ประโยชน์จากเทคโนโลยี Web Protocol เพื่อใช้ในการสร้าง Web Service
API ย่อมาจาก Application Programming Interface คือ ช่องทางการเชื่อมต่อ ,ช่องทางหนึ่งที่จะเชื่อมต่อกับเว็บไซต์ผู้ให้บริการ API จากที่อื่น เป็นตัวกลางที่ทำให้โปรแกรมประยุกต์เชื่อมต่อกับโปรแกรมประยุกต์อื่น หรือเชื่ิอมการทำงานเข้ากับระบบปฏิบัติการ
ดังนั้น ในบทความนี้ เราจะพูดถึงวิธีที่คุณสามารถเริ่มต้นสร้างระบบ REST API ของคุณเองด้วยภาษา Go โดยใช้ Go fiber web framework นี้!
ออกแบบ RESTful API
ก่อนจะลงมือสร้าง API ก็ต้องออกแบบ API กันก่อน ในวันนี้เราจะสร้าง API พื้นฐานเบื้องต้น ดังนี้
POST /todos สร้างข้อมูลใหม่
GET /todos/1 ขอดูข้อมูลไอดีที่ 1
PUT /todos/1 แก้ไขข้อมูลไอดีที่ 1
DELETE /todos/3 ลบข้อมูลไอดีที่ 3
ข้อกำหนดเบื้องต้น
ในการปฏิบัติตามบทความนี้ คุณต้องมีความรู้เกี่ยวกับ พื้นฐานภาษา Go
ซึ่งรวมถึง:
- ติดตั้ง Go บนคอมพิวเตอร์ของคุณแล้ว เรียกใช้
go version
คำสั่งเพื่อตรวจสอบการติดตั้ง Go - สามารถตั้งค่าโปรแกรม Go พื้นฐานได้
- เรียกใช้และสร้างแอปพลิเคชัน Go รวมทั้งทำความเข้าใจวิธีเขียนโค้ด Go
ขั้นตอนการทำ RESTful API
สร้างโฟลเดอร์โมดูลชื่อ todolist และ สร้างไฟล์ go.mod
go mod init todolist

สร้างไฟล์ main.go
เขียนโค้ดดังนี้
package main
import "github.com/gofiber/fiber/v2"
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World!")
})
app.Listen(":3000")
}

ติดตั้ง Go Fiber
Go Fiber เป็นเว็บเฟรมเวิร์กที่สร้างขึ้นบน HTTP ที่รวดเร็ว สามารถใช้ในการจัดการการดำเนินการต่างๆ เช่น การกำหนดเส้นทาง/ปลายทาง มิดเดิลแวร์ คำขอของเซิร์ฟเวอร์
ติดตั้ง Go Fiber ตามลิงค์ https://docs.gofiber.io/ ภายในโฟลเดอร์โมดูล todolist ใช้คำสั่ง
go get github.com/gofiber/fiber/v2

ติดตั้ง GORM
GORM เป็น Go ORM ช่วยให้เรา Map ระหว่างโครงสร้างของ Column ใน Table ของ Database กับ Field ของ Struct ใน Go ได้
ติดตั้ง GORM ตามลิงค์ https://gorm.io/docs/ ภายในโฟลเดอร์โมดูล todolist ใช้คำสั่ง
go get -u gorm.io/gorm

ติดตั้ง PostgreSQL
เริ่มเเรกดาวน์โหลด PostgreSQL มาก่อน สามารถดาวน์โหลดและติดตั้งโปรแกรมที่ : https://www.enterprisedb.com/downloads/postgres-postgresql-downloads ตั้งชื่อ dbname , password และ port ตามต้องการ (ในบทความ dbname คือ goTodo , password คือ lungmaker และ port คือ 54321)
PostgreSQL เป็นระบบจัดการฐานข้อมูลโอเพ่นซอร์สระดับองค์กรที่ทันสมัย ที่พัฒนาโดย PostgreSQL Global Development Group เป็นระบบฐานข้อมูล SQL (Structured Query Language) เชิงวัตถุสัมพันธ์ที่มีประสิทธิภาพและขยายได้สูง
ตัวอย่างการใช้งาน https://gorm.io/docs/connecting_to_the_database.html#Customize-Driver-1
ที่โฟลเดอร์โมดูล todolist ใช้คำสั่ง
go get -u gorm.io/driver/postgres

Create Todo Gorm Model (สร้างการเชื่อมต่อฐานข้อมูล)
สร้างโฟลเดอร์ใหม่ชื่อว่า database และสร้างไฟล์ชื่อ database.go เขียนโค้ดดังนี้
package database
import (
_ "gorm.io/driver/postgres"
"gorm.io/gorm"
)
var (
DBConn *gorm.DB
)

Setup Gorm and Fiber Routes (ตั้งค่าการ Gorm และ เส้นทาง)
สร้างโฟลเดอร์ใหม่ที่ชื่อว่า models และสร้างไฟล์ชื่อ todo.go
เขียนโค้ดดังนี้
package models
import (
"todolist/database"
"github.com/gofiber/fiber/v2"
)
type Todo struct {
ID uint `gorm:"primarykey" json:"id"`
Title string `json:"title"`
Completed bool `json:"completed"`
}
func GetTodos(c *fiber.Ctx) error {
db := database.DBConn
var todos []Todo
db.Find(&todos)
return c.JSON(&todos)
}

แก้ไขโค้ดที่ไฟล์ main.go
แก้ไขโค้ดที่ไฟล์ main.go ตามโค้ดด้านล่าง (ชื่อ dbname , password และ port ให้แก้ไขตามที่เรากำหนดไว้ในขั้นตอนติดตั้ง PostgreSQL)
package main
import (
"github.com/gofiber/fiber/v2"
"todolist/models"
"todolist/database"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"fmt"
)
func helloWord(c *fiber.Ctx) error {
return c.SendString("Hello world")
}
func initDatabase() {
var err error
dsn := "host=localhost user=postgres password=lungmaker dbname=goTodo port=54321"
database.DBConn, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic("Failed to connect to database")
}
fmt.Println("Database connected!")
database.DBConn.AutoMigrate(&models.Todo{})
fmt.Println("Migrated DB")
}
func setupRoutes(app *fiber.App) {
app.Get("/todos", models.GetTodos)
}
func main() {
app := fiber.New()
initDatabase()
app.Get("/", helloWord)
setupRoutes(app)
app.Listen(":8000")
}
แอปพร้อมแล้ว และตอนนี้เราสามารถทดสอบได้โดยใช้คำสั่งต่อไปนี้:
go run main.go

หากคุณไปที่เว็บบราวเซอร์ ป้อน URL http://localhost:8000/ คุณจะเห็นว่า Hello, World! อยู่บนหน้าจอของคุณ

แต่ถ้าหากคุณป้อน URL http://localhost:8000/todos แล้วขึ้นแบบภาพด้านล่าง แสดงว่าขั้นตอนนี้สำเร็จแล้ว

เปิด pgAdmin 4 ของ PostgreSQL จะพบไฟล์ฐานข้อมูลที่เราสร้างขึ้น

และตารางข้อมูลที่เราสร้างขึ้นจากการเขียนโค้ด ด้านล่าง


Create Todos Request (เพิ่มข้อมูล)
ที่ไฟล์ todo.go เพิ่มโค้ดดังนี้
func CreateTodo(c *fiber.Ctx) error {
db := database.DBConn
todo := new(Todo)
err := c.BodyParser(todo)
if err != nil {
return c.Status(500).JSON(fiber.Map{"status": "error", "massage": "Check your input", "data": err})
}
err = db.Create(&todo).Error
if err != nil {
return c.Status(500).JSON(fiber.Map{"status": "error", "massage": "Could not create todo", "data": err})
}
return c.JSON(&todo)
}

ที่ไฟล์ main.go เพิ่มโค้ดดังนี้
app.Post("/todos", models.CreateTodo)

ทดสอบการทำงาน

ติดตั้งโปรแกรม Insomnia
Insomnia เป็นโปรแกรมที่ขาดไม่ได้เลยสำหรับการทำ API , Insomnia คือ โปรแกรมเอาไว้สำหรับทดลองยิง request ไปยัง Service หรือเว็บไซต์ต่างๆ
Download ได้ที่ https://insomnia.rest/download
การใช้งานเบื้องต้น https://www.youtube.com/watch?v=WhCRjd043gE
ทดสอบโค้ดด้านล่าง เลือก POST ด้านล่างเลือกเป็น JSON แล้วป้อน URL http://localhost:8000/todos กดปุ่ม Send
POST จะเป็นการส่งข้อมูลกลับไปหาแหล่งข้อมูล โดยมันจะส่งข้อมูลชุดหนึ่งแนบไปด้วย อย่างในกรณีตัวอย่างนี้คือจะส่งข้อมูลสำหรับให้สร้าง title ใหม่ไปด้วยนั่นเอง
JSON นั้นมีชื่อเต็มๆว่า JavaScript Object Notation เป็นข้อมูลรูปแบบ text ที่มีรูปแบบที่จะเก็บข้อมูลแบบ key, value โดยการเขียนข้อมูลชนิด JSON มีรูปแบบคือ ชื่อฟิลด์ครอบด้วยเครื่องหมาย “ (double quote), เครื่องหมาย : (colon), value แล้วครอบทั้งหมดด้วยเครื่องหมายปีกกา
{
"title": "do something else",
"compleled": false
}
คุณจะเห็นข้อมูลที่ 1 เพิ่มที่ช่อง Preview ด้านขวา

และ ทดสอบโค้ดด้านล่าง -> Send
{
"title": "go developers thailand",
"compleled": false
}
คุณจะเห็นข้อมูลที่ 2 เพิ่มที่ช่อง Preview ด้านขวา

เข้าไปดูที่ฐานข้อมูล จะพบข้อมูลที่เพิ่มเข้าไป


Get Todos By Id (คิวรี่สตริง)
ที่ไฟล์ todo.go เพิ่มโค้ดดังนี้
func GetTodoById(c *fiber.Ctx) error{
id := c.Params("id")
db := database.DBConn
var todo Todo
err := db.Find(&todo, id).Error
if err != nil {
return c.Status(404).JSON(fiber.Map{"status": "error", "massage": "Could not find todo", "data": err})
}
return c.JSON(&todo)
}

ที่ไฟล์ main.go เพิ่มโค้ดดังนี้
app.Get("/todos/:id", models.GetTodoById)

ทดสอบการทำงาน

ไปที่โปรแกรม Insomnia เลือก GET ด้านล่างเลือกเป็น Body แล้วป้อน URL http://localhost:8000/todos/1 กดปุ่ม Send คุณจะเห็นข้อมูลที่ 1 จากการ คิวรี่สตริงใน URL ที่ช่อง Preview ด้านขวา
GET จะเป็นการส่ง URL ร้องขอข้อมูลไปตรงๆ หรือการส่งไปพร้อมกับคิวรี่สตริงใน URL อย่างในกรณีตัวอย่างนี้คือจะส่งข้อมูลสำหรับ คิวรี่สตริง 1 ไปด้วยนั่นเอง

ที่เว็บบราวเซอร์

ป้อน URL http://localhost:8000/todos/2 กดปุ่ม Send คุณจะเห็นข้อมูลที่ 2 จากการ คิวรี่สตริงใน URL ที่ช่อง Preview ด้านขวา

ที่เว็บบราวเซอร์

Update Todos (แก้ไขข้อมูล)
ที่ไฟล์ todo.go เพิ่มโค้ดดังนี้
func UpdateTodo(c *fiber.Ctx) error {
type UpdateTodo struct {
Title string `json:"title"`
Completed bool `json:"completed"`
}
id := c.Params("id")
db := database.DBConn
var todo Todo
err := db.Find(&todo, id).Error
if err != nil {
return c.Status(404).JSON(fiber.Map{"status": "error", "massage": "Could not find todo", "data": err})
}
var updatedTodo UpdateTodo
err = c.BodyParser(&updatedTodo)
if err != nil {
return c.Status(500).JSON(fiber.Map{"status": "error", "massage": "Review your input", "data": err})
}
todo.Title = updatedTodo.Title
todo.Completed = updatedTodo.Completed
db.Save(&todo)
return c.JSON(&todo)
}

ที่ไฟล์ main.go เพิ่มโค้ดดังนี้
app.Put("/todos/:id", models.UpdateTodo)

ทดสอบการทำงาน
ไปที่โปรแกรม Insomnia เลือก PUT ด้านล่างเลือกเป็น JSON แล้วป้อน URL http://localhost:8000/todos/1
PUT นั้นลักษณะการทำงานโดยรวมจะคล้ายกับ POST ต่างกันที่ว่า PUT จะส่งข้อมูลไปยังตำแหน่งที่ยังไม่มีอยู่ และสร้างข้อมูลขึ้นในตำแหน่งนั้นๆ หรือเพื่อไปอัพเดทข้อมูลในตำแหน่งที่มีอยู่แล้ว
การส่ง PUT ไปที่นี้คือจะได้ผลลัพธ์ 2 กรณีคือ
ถ้ายังไม่มี id 1 ให้ทำการสร้าง id ใหม่ด้วย id 1 ด้วยข้อมูลที่ส่งไป
ถ้ามี id 1 อยู่แล้ว ให้อัพเดทข้อมูลด้วยข้อมูลที่ส่งไป
{
"id": 1,
"title": "Golang developer",
"compleled": true
}
กดปุ่ม Send

คุณจะเห็นข้อมูล title ที่ช่อง Preview ด้านขวา เปลี่ยนไปตามค่าที่เรากำหนดใหม่

ที่เว็บบราวเซอร์

Delete Todos (ลบข้อมูล)
ที่ไฟล์ todo.go เพิ่มโค้ดดังนี้
func DeleteTodo(c *fiber.Ctx) error {
id := c.Params("id")
db := database.DBConn
var todo Todo
err := db.Find(&todo, id).Error
if err != nil {
return c.Status(404).JSON(fiber.Map{"status": "error", "massage": "Could not find todo", "data": err})
}
db.Delete(&todo)
return c.SendStatus(200)
}

ที่ไฟล์ main.go เพิ่มโค้ดดังนี้
app.Delete("/todos/:id", models.DeleteTodo)

ทดสอบการทำงาน
ไปที่โปรแกรม Insomnia เลือก GET ด้านล่างเลือกเป็น Body แล้วป้อน URL http://localhost:8000/todos/ กดปุ่ม Send คุณจะเห็นข้อมูล id ที่ 1 ถึง id 3 ที่ช่อง Preview ด้านขวา ซึ่ง id ที่ 3 ที่มีการเพิ่มใหม่เข้าไป มี ข้อมูลซ้ำกับ id ที่ 2 จึงต้องการลบออกไป

เลือก DELETE ด้านล่างเลือกเป็น Body แล้วป้อน URL http://localhost:8000/todos/3 กดปุ่ม Send
DELETE จะเป็นการสั่งลบข้อมูลที่มีอยู่แล้ว เช่น เพื่อสั่งให้ลบข้อมูล id 3


ทดสอบ เลือก GET แล้วป้อน URL http://localhost:8000/todos/ กดปุ่ม Send จะเห็นว่า ข้อมูล id ที่ 3 ถูกลบออกไปแล้ว

Enable CORS
การใช้ CORS https://docs.gofiber.io/api/middleware/cors เพื่อ อณุญาติให้ Port ของ back-end และ front-end ที่ต่างกันสามารถทำงานร่วมกันได้
มีขั้นตอนดังนี้
import เพิ่มเข้าไปที่ไฟล์ main.go
"github.com/gofiber/fiber/v2/middleware/cors"

ที่ ฟังค์ชัน main เพิ่มโค้ดดังนี้
app.Use(cors.New())

ทดสอบการทำงาน ถ้าสามารถทำงานได้ app ก็พร้อมสำหรับในการทำงานกับ front-end ที่ต่างกันต่อไป

credit : https://www.udemy.com/course/build-a-todolist-with-go-golang-fiber-and-react/