Versioning Strategies
เมื่อการเปลี่ยนแปลงจะทำให้ client ที่มีอยู่พัง คุณจำเป็นต้องมี versioning strategy เพื่อให้ client เก่าและใหม่อยู่ร่วมกันได้ มีสามที่ทั่วไปที่นิยมใช้สำหรับวางเวอร์ชัน
Breaking กับ non-breaking
หัวข้อที่มีชื่อว่า “Breaking กับ non-breaking”อันดับแรก ตัดสินใจก่อนว่าคุณจำเป็นต้องมีเวอร์ชันใหม่จริงหรือไม่ การเปลี่ยนแปลงแบบ non-breaking (เพิ่มเติม) ไม่เคยต้องการเวอร์ชันใหม่:
- การเพิ่ม endpoint ใหม่ หรือ field ใหม่ที่เป็น optional
- การเพิ่ม query parameter ใหม่ที่เป็น optional
- การเพิ่มค่าใหม่เข้าไปใน enum ที่เป็น output-only (หาก client ได้รับการบอกให้ยอมรับค่าที่ไม่รู้จักได้)
การเปลี่ยนแปลงแบบ breaking ต้องการเวอร์ชันใหม่: การลบหรือเปลี่ยนชื่อ field, การเปลี่ยน type, การทำให้ field ที่เป็น optional กลายเป็น required, หรือการเปลี่ยนความหมายของ response
สามกลยุทธ์
หัวข้อที่มีชื่อว่า “สามกลยุทธ์”- URI versioning —
GET /v1/articlesมองเห็นได้ชัดเจนที่สุดและ route กับ cache ได้ง่ายที่สุด; เวอร์ชันอยู่ตรงนั้นใน URL เลย ข้อเสีย: resource เดียวกันจะอยู่ที่ URI สองที่ในเวอร์ชันต่างกัน - Header versioning — header แบบ custom หรือมาตรฐาน เช่น
API-Version: 2ทำให้ URI สะอาด แต่เวอร์ชันมองไม่เห็นใน log และลองผ่าน browser ได้ยากกว่า - Media-type versioning — เจรจาผ่าน
Accept: application/vnd.example.article+json;version=2เป็นวิธีที่ RESTful ที่สุด (เวอร์ชันเป็นส่วนหนึ่งของ representation) แต่ใช้งานยุ่งยากที่สุด
GET /v1/articles # URI versioningGET /articles # header versioningAPI-Version: 2
GET /articles # media-type versioningAccept: application/vnd.example.article+json;version=2การเลือก
หัวข้อที่มีชื่อว่า “การเลือก”สำหรับทีมส่วนใหญ่ URI versioning ชนะด้วยความเป็นปฏิบัตินิยม คือชัดเจน เป็นมิตรกับ cache และทดสอบง่ายมาก ไม่ว่าคุณจะเลือกแบบไหน ให้ทำเวอร์ชัน ทั้ง API ในระดับหยาบ (v1, v2) ไม่ใช่ทำเวอร์ชันแต่ละ endpoint แยกกัน — เวอร์ชันรายต่อ endpoint จะทำให้ support matrix บานปลาย
| Strategy | ข้อดี | ข้อเสีย | เหมาะกับ |
|---|---|---|---|
URI versioning (/v1/) | ชัดเจน, cache ง่าย, test ง่าย | resource มีสอง URI | ส่วนใหญ่ — practical choice |
Header versioning (API-Version: 2) | URI สะอาด | มองไม่เห็นใน log, debug ยาก | Internal API ที่ control client |
Media-type (Accept: ...;version=2) | RESTful ที่สุด | ซับซ้อน, tooling support น้อย | Rarely used in practice |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”Version เฉพาะ Endpoint แทน API ทั้งหมด อาการ:
/v1/usersแต่/v2/ordersใน API เดียวกัน- client ต้อง track version ของแต่ละ endpoint แยกกัน
- version ทั้ง API พร้อมกัน:
/v1/usersและ/v1/orders→/v2/usersและ/v2/orders
ไม่ Deprecate อย่าง Graceful อาการ:
- ปิด
/v1/โดยไม่แจ้งล่วงหน้า — client พังทันที - ไม่มี migration guide หรือ timeline ชัดเจน
- ใช้
DeprecationและSunsetheader:Sunset: Sat, 31 Dec 2024 23:59:59 GMT
💡 ตัวอย่างจากของจริง
Stripe API:
- versioning ผ่าน
Stripe-Versionheader — ไม่เปลี่ยน URI- account ถูก lock ที่ version ที่สร้าง — ไม่ break เมื่อ Stripe release version ใหม่
GitHub API:
- URI versioning:
/v3/(REST),/graphql(GraphQL v4)- deprecation notice ล่วงหน้า 12 เดือน พร้อม
Deprecationheader