เพราะ API ไม่คงที่ — เมื่อเวลาผ่านไป:
- เปลี่ยน structure ของ response
- เปลี่ยน validation หรือ logic
- ย้าย/ลบ/เพิ่ม endpoint
หากไม่มีเวอร์ชัน → Client พังทันทีเมื่อมีการเปลี่ยน
🧠 แนวทางจัดการ API Version สำหรับ Tech Lead
✅ 1. URI Versioning (นิยมที่สุด)
GET /api/v1/users
- ชัดเจน, เข้าใจง่าย
- สามารถมีหลาย version พร้อมกันได้
- เหมาะสำหรับ public API หรือ third-party client
✔ เหมาะกับ REST API ที่เปลี่ยนบ่อย
✅ 2. Header Versioning
GET /users
Headers: Accept-Version: v2
- Clean URL
- แต่ Client ต้องรู้วิธีตั้ง header → อาจไม่เหมาะกับ browser
✔ เหมาะกับ API ภายในองค์กร ที่ควบคุม client ได้
🧰 แนวทางที่ควรวางไว้แบบนี้
| ด้าน | แนวทาง |
|---|---|
| ✅ เวอร์ชันใน URL | /api/v1/ (ชัดเจนสุด) |
| ✅ Maintain version เดิม | อย่าเปลี่ยน behavior ของ v1 |
| ✅ Deprecate แบบมีแผน | ประกาศล่วงหน้า เช่น “v1 จะหยุดให้บริการใน 6 เดือน” |
| ✅ มี changelog | ชัดเจนว่า v2 เปลี่ยนอะไร |
| ✅ Document ทุก version | แยกชัดว่าแต่ละ version รองรับอะไร |
| ✅ ใช้ API Gateway | เช่น Kong / Apigee เพื่อจัดการ version routing |
🧠 เมื่อไหร่ควรเพิ่มเวอร์ชัน?
| คำถาม | คำตอบ |
|---|---|
เปลี่ยนชื่อ field → username → user_name | ✅ v2 |
| เพิ่ม optional field ใหม่ | ❌ ไม่จำเป็น (Backward compatible) |
| เปลี่ยน validation rule (จาก optional → required) | ✅ v2 |
| เปลี่ยน resource path | ✅ v2 |
| เพิ่ม endpoint ใหม่ (โดยไม่กระทบ endpoint เดิม) | ❌ ไม่จำเป็น |
ข้อควรระวัง
- อย่าลบ version เก่าแบบทันที!
- อย่าทำ breaking change โดยไม่แจ้ง client
- เวอร์ชัน API ไม่ควรขึ้นกับเวอร์ชันของระบบภายใน (เช่น
app-v1.2.3) - ต้อง version เฉพาะ “public interface” ไม่จำเป็นต้อง version internal service
GET /api/v1/products → สินค้าแบบเก่า
GET /api/v2/products → มีฟิลด์ใหม่, รูปแบบ response ใหม่
ตัวอย่าง
@RestController
@RequestMapping("/api/v1/users")
public class UserV1Controller {
@GetMapping
public String getUsersV1() {
return "User API v1";
}
}
@RestController
@RequestMapping("/api/v2/users")
public class UserV2Controller {
@GetMapping
public String getUsersV2() {
return "User API v2";
}
}










