มาสร้าง RESTful Web Service ด้วย Gin (Go web framework)
วันก่อนได้ถามน้องที่ทำงานว่าใช้ Go web framework อะไร ก็ได้คำตอบว่าใช้ Gin web framework ซึ่งก็ตรงกับ poll ที่เคยสอบถามในกลุ่ม Golang Thailand และก็ดูจาก Github แล้วก็เจอว่ายอด Start มากกว่า Echo ประมาณหนึ่งเท่าตัว แสดงว่า Gin web framework เป็นที่นิยมชมชอบของ Go developer มากมากทีเดียว ดังนั้นในวันนี้เลยจะมาลองใช้ Gin web framework มาทำ RESTful Web Service ดูว่าจะมีความยากง่ายอย่างไร
Gin?
Gin เป็น web framework ที่เขียนด้วยภาษา Go ซึ่งมี feature เหมือนกับ martini API แต่มีประสิทธิภาพมากกว่า มีความเร็วมากกว่าถึง 40 เท่า ด้วย httprouter ถ้าต้องการประสิทธิภาพและ productivity ที่ดีเยี่ยม คุณจะหลงรัก Gin
Gin มี feature เด่นๆ ที่อยู่ในเว็บของ Gin ดังนี้
- Fast — Gin ใช้ Redix tree routing ทำให้ใช้ memory foot print ที่เล็ก ไม่มี reflection ทำให้ API มีประสิทธิภาพสูง
- Middleware support — incoming HTTP request จะถูกจัดการด้วย chain ของ middleware และ action สุดท้าย
- Crash-free — Gin สามารถจัดการกับ panic ที่เกิดขึ้นจาก HTTP request และจัดการ recovery panic นั้น ซึ่งจะทำให้ server ใช้งานได้ตลอดเวลา
- JSON validation — Gin สามารถแปลงและตรวจสอบ JSON ของ HTTP request
- Routes grouping — เป็นการจัดกลุ่ม routes ของ request ว่า request ไหนต้องมีการ authorization หรือไม่จำเป็นต้องมี การแยก request ด้วย version ของ API โดยสามารถจัดกลุ่มได้อย่างไม่จำกัด และไม่กระทบกับประสิทธิภาพ
- Error management — Gin มีวิธีการที่สะดวกสบายที่รวบรวม error ที่เกิดขึ้นในระหว่าง HTTP request และให้ middleware จัดการต่อได้
- Rendering build-in — Gin ง่ายสำหรับสร้าง API ที่ render เป็น JSON, XML และ HTML
- Extendable — สร้าง middleware ใหม่ได้ง่ายมาก เพื่อขยายความสามารถของ Gin
Install
ติดตั้ง Gin package ด้วยคำสั่ง go get
ก็จะได้ Gin ใน GOPATH
เป็นที่เรียบร้อย
go get -u github.com/gin-gonic/gin
ใช้งาน Gin ก็เพียง import github.com/gin-gonic/gin
เข้ามาในไฟล์ .go
import "github.com/gin-gonic/gin"
Create Project
หลังจากติดตั้ง Gin ใน GOPATH
เป็นที่เรียบร้อยก็สร้าง project folder ใน GOPATH
ตัวอย่างของผมก็จะเป็น
mkdir $GOPATH/src/github.com/iphayao/gin-restful-api
ซึ่งในเว็บของ Gin มี quick start สำหรับสร้าง RESTFul Web Service ดังนั้นเราจะมาสร้าง endpoint อย่างง่ายดูเพื่อตรวจสอบว่าเราติดตั้ง Gin ทำงานได้ไหม
สร้างไฟล์ server.go
แล้ว import github.com/gin-gonic/gin
และ net/http
เข้ามาในไฟล์ แล้ว
- สร้าง function
main()
โดยใช้r := gin.Default()
เพื่อสร้าง Engine instance ของ Gin (แต่ก็ใช้r := gin.New()
ได้เหมือนกัน แต่gin.Default()
จะมี middleware Logger และ Recovery ติดตั้งมาให้) - ใช้ function
GET
เพื่อ map HTTP method GET และ path/ping
โดยมี function มาจัดการกับ request นี้ และ response เป็นรูปแบบ JSON มีค่าเป็น{ “message” : “pong” }
- และใช้
r.Run()
เพื่อ start Web Server ด้วย port เริ่มต้นเป็น8080
เมื่อใช้คำสั่ง go run server.go
เพื่อเริ่มต้นการทำงานของ Web Server จะเห็น GIN-debug
แสดงรายละเอียดการทำงานของ Gin Engine
เมื่อใช้ cURL
ทดสอบแบบง่ายๆ curl localhost:8080/ping
และ response เป็น {"message":"pong"}
จะมีสถานะแสดงบน GIN-debug
ด้วย
{"message":"pong"}
จะเห็นได้ว่าเราสามารถใช้งาน Gin web framework ได้แล้ว ต่อไปเราจะสร้าง endpoint ต่างๆ ของ RESTful Web Service เพื่อทำ CRUD operation ง่ายๆ
Routing
สร้าง router สำหรับ route แต่ละ endpoint ของ CRUD operation ไปยัง handler function ต่างๆ เพื่อจัดการกับ resource customers
ด้วย CustomerHandler
ใน function setupRouter()
และเรียกใช้ function setupRouter()
ใน functionmain()
ในส่วนที่ติดต่อกับ database จะใช้ GORM
ORM framework ติดต่อกับ MySQL ซึ่งจะใช้ function Initialize
ของ struct CustomerHandler
เพื่อเปิดการเชื่อมต่อ และ AutoMigrate
model Customer
กับ database
สร้าง struct Customer
ที่เป็นตัวแทนของ Customer ที่มี field Id
ซึ่งเป็น primary key เพิ่มค่าอัตโนมัติด้วย GORM
, FistName
, LastName
, Age
และ Email
Handler
ส่วน Handler ที่เป็นตัวจัดการ opration ต่างๆ ของ CRUD operation เป็น function ปรกติของ Go ใช้ *gin.Context
เป็น Context ที่ส่งค่าต่างๆ จาก HTTP request ไป middleware และ response กลับ ซึ่งเป็น function ของ CustomerHandler
ที่ผูกกับ router ไปแล้ว
Gin จะมี function ShouldBindJSON
เพื่อ bind request body ในรูปแบบ JSON กับ struct (Gin มี function แบบนี้อีกหลาย function เพื่อรองรับหลากหลายรูปแบบของข้อมูล และ URL ด้วย)
ใน Gin จะ response กลับเป็นแบบ JSON หรือ XML ได้ และจะ response เฉพาะ HTTP Status อย่างเดียวก็ได้
Testing
ในบทความนี้จะเขียน Test เพื่อทดสอบ RESTful Web Service ทำ CRUD Operation โดยใช้ packagenet/http/httptest
และ testify1
ในไฟล์ server_test.go
เมื่อ run คำสั่ง go test
เพื่อทดสอบ RESTful Web Service ด้วย Test case ที่สร้างขึ้น จะได้ผลลัพย์ดังนี้ (อาจจะต้องใช้คำสั่ง export GIN_MODE=test
เพื่อเปลี่ยนโหมดของ Gin ให้อยู่ใน mode test และไม่แสดง debug log ต่างๆ)
สรุป
จากที่ได้ทดลองใช้ Gin web framework ของ Go มาสร้าง RESTful Web Service ก็พบว่าใช้งานง่ายเช่นเดียวกับ framework อื่น และด้วยที่มี mode debug ทำให้ Gin แสดง log ของแต่ละ request ได้ทำให้ดูง่าย สมกับเป็น web framework ที่มียอด star มากที่สุด แต่ในบทความนี้ยังไม่ได้ทดสอบประสิทธิภาพความเร็วของ Gin เทียบกับ framework ตัวอื่น