Pair Programming : ระบบบริหารจัดการร้านกาแฟ Online
ให้นักศึกษาพัฒนา REST API สำหรับระบบบริหารจัดการร้านกาแฟ Online อย่างง่าย โดยใช้ Gin Framework
ความต้องการของระบบ
- ระบบสามารถแสดงรายการเมนูกาแฟทั้งหมด
- ระบบสามารถค้นหาเมนูกาแฟด้วยชื่อหรือประเภท
- ระบบสามารถแสดงรายละเอียดของเมนูกาแฟจากรหัสเมนู
- ระบบสามารถรับ Order ใหม่และคำนวณเวลาที่คาดว่าจะเสร็จ
- ระบบต้องมี Middleware สำหรับบันทึกเวลาการเข้าถึงและ Endpoint ที่ถูกเรียกใช้งาน
โครงสร้างข้อมูล
// เมนูกาแฟ
type Coffee struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"` // เช่น "Espresso", "Latte", "Cappuccino"
Price float64 `json:"price"`
Description string `json:"description"`
}
// ออร์เดอร์
type Order struct {
OrderID string `json:"order_id"`
CoffeeID string `json:"coffee_id"`
Quantity int `json:"quantity"`
CreatedAt string `json:"created_at"`
EstimatedDelivery string `json:"estimated_delivery"`
Status string `json:"status"` // "Pending", "In Progress", "Completed"
}
ข้อมูลตัวอย่าง
var coffees = []Coffee{
{ID: "c001", Name: "Espresso", Type: "Espresso", Price: 60, Description: "เข้มข้น กลมกล่อม"},
{ID: "c002", Name: "Americano", Type: "Espresso", Price: 65, Description: "เอสเพรสโซ่ผสมน้ำร้อน"},
{ID: "c003", Name: "Latte", Type: "Latte", Price: 75, Description: "เอสเพรสโซ่ผสมนมร้อน"},
{ID: "c004", Name: "Cappuccino", Type: "Cappuccino", Price: 75, Description: "เอสเพรสโซ่ผสมนมร้อนและฟองนม"},
{ID: "c005", Name: "Mocha", Type: "Mocha", Price: 80, Description: "เอสเพรสโซ่ผสมนมร้อนและช็อกโกแลต"},
}
Endpoints ที่ต้องพัฒนา
GET /coffees แสดงรายการเมนูกาแฟทั้งหมด
GET /coffees/:id แสดงรายละเอียดเมนูกาแฟจากรหัส
GET /coffees/search ค้นหาเมนูกาแฟด้วย query parameters (name และ type)
POST /orders สร้าง Order ใหม่ (ใช้เวลาเตรียม 5 นาทีต่อ 1 แก้ว)
GET /orders/:order_id - ดูสถานะของ Order
1. GET /coffees - แสดงรายการเมนูกาแฟทั้งหมด
Request
GET /coffees HTTP/1.1
Host: localhost:8080
Response (HTTP Status 200 OK)
{
"coffees": [
{
"id": "c001",
"name": "Espresso",
"type": "Espresso",
"price": 60,
"description": "เข้มข้น กลมกล่อม"
},
{
"id": "c002",
"name": "Americano",
"type": "Espresso",
"price": 65,
"description": "เอสเพรสโซ่ผสมน้ำร้อน"
},
{
"id": "c003",
"name": "Latte",
"type": "Latte",
"price": 75,
"description": "เอสเพรสโซ่ผสมนมร้อน"
},
{
"id": "c004",
"name": "Cappuccino",
"type": "Cappuccino",
"price": 75,
"description": "เอสเพรสโซ่ผสมนมร้อนและฟองนม"
},
{
"id": "c005",
"name": "Mocha",
"type": "Mocha",
"price": 80,
"description": "เอสเพรสโซ่ผสมนมร้อนและช็อกโกแลต"
}
]
}
2. GET /coffees/:id - แสดงรายละเอียดเมนูกาแฟจากรหัส
Request (กรณีปกติ)
GET /coffees/c003 HTTP/1.1
Host: localhost:8080
Response (กรณีปกติ)
{
"id": "c003",
"name": "Latte",
"type": "Latte",
"price": 75,
"description": "เอสเพรสโซ่ผสมนมร้อน"
}
Request (กรณีไม่พบ)
GET /coffees/c999 HTTP/1.1
Host: localhost:8080
Response (กรณีไม่พบ)
{
"error": "Coffee not found"
}
3. GET /coffees/search - ค้นหาเมนูกาแฟด้วย query parameters
Request (ค้นหาด้วยชื่อ)
GET /coffees/search?name=lat HTTP/1.1
Host: localhost:8080
Response (ค้นหาด้วยชื่อ)
{
"coffees": [
{
"id": "c003",
"name": "Latte",
"type": "Latte",
"price": 75,
"description": "เอสเพรสโซ่ผสมนมร้อน"
}
]
}
Request (ค้นหาด้วยประเภท)
GET /coffees/search?type=Espresso HTTP/1.1
Host: localhost:8080
Response (ค้นหาด้วยประเภท)
{
"coffees": [
{
"id": "c001",
"name": "Espresso",
"type": "Espresso",
"price": 60,
"description": "เข้มข้น กลมกล่อม"
},
{
"id": "c002",
"name": "Americano",
"type": "Espresso",
"price": 65,
"description": "เอสเพรสโซ่ผสมน้ำร้อน"
}
]
}
Request (ไม่มีผลลัพธ์)
GET /coffees/search?name=frappe HTTP/1.1
Host: localhost:8080
Response (ไม่มีผลลัพธ์)
{
"coffees": []
}
4. POST /orders - สร้างออร์เดอร์ใหม่
Request (กรณีปกติ)
POST /orders HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{
"coffee_id": "c003",
"quantity": 2
}
Response (กรณีปกติ)
{
"order_id": "o12345",
"coffee_id": "c003",
"quantity": 2,
"created_at": "2025-03-03T15:30:45+07:00",
"estimated_delivery": "2025-03-03T15:40:45+07:00",
"status": "Pending"
}
Request (รหัสกาแฟไม่ถูกต้อง)
POST /orders HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{
"coffee_id": "c999",
"quantity": 1
}
Response (รหัสกาแฟไม่ถูกต้อง)
{
"error": "Coffee not found"
}
Request (จำนวนไม่ถูกต้อง)
POST /orders HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{
"coffee_id": "c003",
"quantity": 0
}
Response (จำนวนไม่ถูกต้อง)
{
"error": "Invalid quantity, must be greater than 0"
}
5. GET /orders/:order_id - ดูสถานะของ Order
Request (กรณีปกติ)
GET /orders/o12345 HTTP/1.1
Host: localhost:8080
Response (กรณีปกติ)
{
"order_id": "o12345",
"coffee_id": "c003",
"quantity": 2,
"created_at": "2025-03-03T15:30:45+07:00",
"estimated_delivery": "2025-03-03T15:40:45+07:00",
"status": "In Progress"
}
Request (กรณีไม่พบออร์เดอร์)
GET /orders/o99999 HTTP/1.1
Host: localhost:8080
Response (กรณีไม่พบออร์เดอร์)
{
"error": "Order not found"
}
ตัวอย่างโครงสร้าง Middleware
func LoggingMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// บันทึกเวลาเริ่มต้น
startTime := time.Now()
// บันทึก Endpoint ที่ถูกเรียก
path := c.Request.URL.Path
// ดำเนินการต่อไปยังส่วนถัดไป (handler หรือ middleware ถัดไป)
c.Next()
// บันทึกเวลาสิ้นสุดและคำนวณเวลาที่ใช้
endTime := time.Now()
latency := endTime.Sub(startTime)
// แสดงข้อมูลการเข้าถึง
log.Printf("| %s | %s | %v |", c.Request.Method, path, latency)
}
}
HTTP Status Code ที่ควรใช้
200 OK สำหรับการเรียกดูข้อมูลสำเร็จ
201 Created สำหรับการสร้างข้อมูลใหม่สำเร็จ
400 Bad Request สำหรับข้อมูลที่ส่งมาไม่ถูกต้อง
404 Not Found สำหรับไม่พบข้อมูลที่ร้องขอ
500 Internal Server Error สำหรับข้อผิดพลาดภายในเซิร์ฟเวอร์