การสร้าง API จริงครั้งแรกของผมด้วย Go และ Gin

ผมกำลังเปลี่ยนจากการเรียนรู้ทฤษฎีไปสู่การลงมือปฏิบัติจริง

หลังจากศึกษาเรื่อง structs, interfaces, goroutines และการจัดการ error ผมก็ได้สร้าง Orders API ที่ใช้งานได้จริงโดยใช้ Go และ Gin framework

API นี้ทำงาน 3 อย่าง:

  • สร้างคำสั่งซื้อ
  • ดึงข้อมูลคำสั่งซื้อตาม ID
  • แสดงรายการคำสั่งซื้อทั้งหมด

ผมเลือกใช้ Gin เพราะมันช่วยให้การทำ routing และ middleware ง่ายขึ้น โดยมี helper functions อย่าง c.JSON และ c.AbortWithStatusJSON ซึ่งเครื่องมือเหล่านี้ช่วยลดการเขียนโค้ดที่ซ้ำซ้อน

โครงสร้างโปรเจกต์: ผมใช้การจัดวางแพ็กเกจแบบ flat เพื่อให้โค้ดดูสะอาดตา:

  • handler: จัดการ HTTP logic
  • model: กำหนดโครงสร้างข้อมูล (data shapes)
  • store: จัดการการจัดเก็บข้อมูล
  • middleware: จัดการเรื่อง logging และ requests

ทางเลือกทางเทคนิคที่สำคัญ:

• การตรวจสอบความถูกต้องของข้อมูล (Data Validation) ผมใช้ struct tags สำหรับการทำ JSON serialization และยังใช้ Gin binding tags ด้วย เพื่อให้มั่นใจว่าฟิลด์ที่จำเป็นต้องมีอยู่ครบถ้วน และจำนวน (amounts) ต้องมากกว่าศูนย์

• การจัดเก็บข้อมูลและการทำงานแบบขนาน (Persistence and Concurrency) เวอร์ชันปัจจุบันใช้การจัดเก็บข้อมูลในหน่วยความจำ (in-memory store) โดยผมใช้ sync.RWMutex เพื่อจัดการการเข้าถึงข้อมูลแบบพร้อมกัน (concurrent access) ซึ่งช่วยให้สามารถอ่านข้อมูลได้หลายรายการพร้อมกัน แต่ยังคงความปลอดภัยในการเขียนข้อมูล

• อินเทอร์เฟซ (Interfaces) ตัว handler จะขึ้นอยู่กับ OrderStore interface โดยไม่สนใจว่าข้อมูลจะถูกเก็บไว้ในหน่วยความจำหรือในฐานข้อมูล ซึ่งช่วยให้การเปลี่ยนเลเยอร์การจัดเก็บข้อมูล (storage layer) ทำได้ง่าย

• การจัดการข้อผิดพลาด (Error Handling) ผมใช้ errors.Is เพื่อตรวจสอบข้อผิดพลาดเฉพาะเจาะจง เช่น ErrNotFound ซึ่งช่วยให้ API สามารถส่ง HTTP status code 404 ที่ถูกต้องกลับไปยังผู้ใช้ได้

• มิดเดิลแวร์ (Middleware) ผมได้สร้าง custom logger ขึ้นมาเอง เพื่อติดตาม method, path, status code และระยะเวลาในการประมวลผลคำขอ (request duration)

การตั้งค่านี้เป็นการรวบรวมทุกอย่างที่ได้เรียนรู้มาจากส่วนก่อนหน้าเข้าด้วยกัน มันเป็นรากฐานที่ใช้งานได้จริง มีโครงสร้างที่ดี และสามารถขยายระบบได้ (scalable)

แล้วคุณล่ะ มีวิธีการจัดโครงสร้างโปรเจกต์ Go อย่างไร? คุณชอบแบบ flat packages หรือแบบที่มีการซ้อนกันลึกๆ ตามโดเมน (domain-driven nesting)?

แหล่งที่มา: https://dev.to/mihirmohapatra/building-my-first-real-api-in-go-with-gin-3kio