Programming
น้องๆ เคยสงสัยไหมว่าทำไมบางทีเราอัพเดทแอปแล้วมันยังใช้กับ backend เก่าได้? หรือบางที API ที่เราเรียกใช้มันก็ยังทำงานอยู่ แม้ว่า backend จะเปลี่ยนไปเยอะแล้วก็ตาม? นั่นแหละครับ คือสิ่งที่เรียกว่า API Versioning
API Versioning คือการที่เราจัดการ API ให้มีหลายเวอร์ชั่น เพื่อรองรับการเปลี่ยนแปลงของระบบ โดยที่ client เก่าๆ ยังสามารถใช้งานได้อยู่ และ client ใหม่ๆ ก็ได้ใช้ features ใหม่ๆ
ทำไมมันถึงสำคัญ? ลองนึกภาพว่าเรามีแอปที่คนใช้เป็นล้านๆ คน แล้วเราดันไปเปลี่ยน API แบบไม่บอกไม่กล่าว ลูกค้าเก่าที่ใช้แอปเวอร์ชั่นเก่าอยู่ก็จะใช้งานไม่ได้ทันที เกิดเป็นดราม่าแน่นอนครับ สมัยผมทำร้านเน็ตนี่เคยเจอเคสแบบนี้เลย ลูกค้าโวยวายกันเต็มร้าน เพราะโปรแกรมคิดเงินใช้งานไม่ได้เพราะ API ล่ม! ดังนั้น API Versioning จึงสำคัญมากๆ ในการ maintain ระบบให้ stable และ user experience ที่ดี
SemVer คือมาตรฐานในการตั้ง version ที่บอกความหมายของการเปลี่ยนแปลงในแต่ละ version ครับ มันจะอยู่ในรูปแบบ MAJOR.MINOR.PATCH เช่น 1.2.3
ยกตัวอย่างเช่น ถ้าเราเปลี่ยน API endpoint จาก /users เป็น /customers อันนี้ถือเป็น MAJOR change เพราะ client เก่าจะใช้งานไม่ได้แล้ว เราก็ต้อง bump version เป็น 2.0.0
REST (Representational State Transfer) เป็น architecture style ที่นิยมใช้ในการสร้าง API ครับ การเข้าใจหลักการของ REST จะช่วยให้เราออกแบบ API ที่ดีและง่ายต่อการทำ versioning
หลักการสำคัญของ REST คือ:
สมัยผมทำร้านเน็ตนี่ REST ยังไม่ฮิตเท่าไหร่ ส่วนใหญ่ใช้ SOAP กัน แต่พอ REST มานี่ชีวิตง่ายขึ้นเยอะเลย
การทำ API Versioning ไม่ได้ยากอย่างที่คิดครับ มีหลายวิธีให้เลือกใช้ ขึ้นอยู่กับความเหมาะสมของแต่ละโปรเจค
วิธีนี้คือการใส่ version ไว้ใน URL ครับ เช่น /v1/users, /v2/users
GET /v1/users HTTP/1.1
Host: api.example.com
ข้อดีคือเข้าใจง่าย ตรงไปตรงมา แต่ข้อเสียคือ URL จะยาวและดูรก
วิธีนี้คือการส่ง version ผ่าน HTTP header ครับ เช่น Accept: application/vnd.example.v1+json
GET /users HTTP/1.1
Host: api.example.com
Accept: application/vnd.example.v1+json
ข้อดีคือ URL จะสั้นและสวยงาม แต่ข้อเสียคือต้อง configure server ให้รองรับ header versioning
วิธีนี้คือการส่ง version ผ่าน query parameter ครับ เช่น /users?version=1
GET /users?version=1 HTTP/1.1
Host: api.example.com
ข้อดีคือ implementation ง่าย แต่ข้อเสียคือ URL จะดูรกและไม่ค่อย clean
ดูวิดีโอเพิ่มเติมเกี่ยวกับApi Versioning Strategies Guide:
นอกจาก 3 วิธีที่กล่าวมาแล้ว ก็ยังมีวิธีอื่นๆ อีก เช่น Content Negotiation, Custom Headers แต่ 3 วิธีแรกเป็นที่นิยมใช้กันมากที่สุด
เลือกวิธีไหนดี? ขึ้นอยู่กับความชอบและความเหมาะสมของแต่ละโปรเจคครับ ไม่มีวิธีไหนดีที่สุด
| Strategy | ข้อดี | ข้อเสีย | ความเหมาะสม |
|---|---|---|---|
| URI Versioning | เข้าใจง่าย, ตรงไปตรงมา | URL ยาว, ดูรก | เหมาะสำหรับ API ที่ต้องการความชัดเจน |
| Header Versioning | URL สั้น, ดูสวยงาม | ต้อง configure server | เหมาะสำหรับ API ที่ต้องการความสวยงาม |
| Query Parameter Versioning | Implementation ง่าย | URL รก, ไม่ clean | เหมาะสำหรับ API ที่ต้องการความรวดเร็วในการ implement |
สมัยผมทำร้านเน็ตนี่ ผมเลือกใช้ URI Versioning เพราะมันง่ายและตรงไปตรงมาดี ไม่ต้องคิดเยอะ
อย่าลืมแวะไปอ่านบทความอื่นๆ ใน SiamCafe Blog นะครับ มีเรื่อง IT สนุกๆ อีกเยอะเลย
หวังว่าบทความนี้จะเป็นประโยชน์กับน้องๆ นะครับ ถ้ามีคำถามอะไร ถามมาได้เลย SiamCafe Blog ยินดีตอบเสมอ
เอาล่ะน้องๆ มาถึงตรงนี้แล้ว หวังว่าคงพอเห็นภาพรวมของ API Versioning กันบ้างแล้วนะ สมัยผมทำ SiamCafe เนี่ย เรื่องพวกนี้ยังไม่ค่อยมีใครพูดถึงกันเท่าไหร่ แต่พอระบบมันเริ่มใหญ่ขึ้น เริ่มมีคนมาใช้ API เราเยอะขึ้นเท่านั้นแหละ ปัญหาตามมาเพียบเลย
สิ่งที่ผมอยากจะเน้นย้ำจากประสบการณ์จริงคือ "คิดเผื่ออนาคต" เสมอ อย่าคิดว่า API ที่เราทำวันนี้ มันจะอยู่ไปตลอดกาล มันต้องมีการเปลี่ยนแปลงแน่นอน ไม่ว่าจะเพื่อเพิ่มฟีเจอร์ใหม่ แก้บั๊ก หรือปรับปรุงประสิทธิภาพ เพราะฉะนั้น การวางแผนเรื่อง Versioning ตั้งแต่เนิ่นๆ จะช่วยประหยัดเวลาและค่าใช้จ่ายในระยะยาวได้เยอะเลย
อีกเรื่องที่สำคัญคือ "สื่อสาร" กับผู้ใช้งาน API ของเราให้ชัดเจน ว่าเราจะมีการเปลี่ยนแปลงอะไรบ้าง จะมีผลกระทบอะไรบ้าง และต้องเตรียมตัวอย่างไรบ้าง การสื่อสารที่ดีจะช่วยลดความขัดแย้ง และทำให้ผู้ใช้งาน API ของเรามั่นใจในระบบของเรามากขึ้น
เอาล่ะ มาดูเทคนิคที่ผมเคยใช้จริงสมัยทำร้านเน็ตกันบ้าง
Accept: application/vnd.siamcafe.v2+jsonสมมติว่าเราจะใช้ Header ในการระบุ Version ของ API ใน PHP เราสามารถทำได้ประมาณนี้:
<?php
$version = $_SERVER['HTTP_ACCEPT']; // ดึงค่า Accept Header
if (strpos($version, 'vnd.siamcafe.v2') !== false) {
// เรียกใช้งาน API Version 2
echo json_encode(['message' => 'Hello from API Version 2']);
} else {
// เรียกใช้งาน API Version 1 (Default)
echo json_encode(['message' => 'Hello from API Version 1']);
}
?>
โค้ดข้างบนเป็นแค่ตัวอย่างง่ายๆ นะครับ ในความเป็นจริง อาจจะต้องมีการตรวจสอบและจัดการ Error Handling ให้รัดกุมกว่านี้
นอกจากนี้ อย่าลืมเข้าไปอ่านบทความอื่นๆ เพิ่มเติมได้ที่ SiamCafe Blog นะครับ
ถ้าเป็นบั๊กที่ร้ายแรง (Critical Bug) ที่ส่งผลกระทบต่อการทำงานของระบบอย่างมาก ควรทำการ Patch API Version เก่า และแจ้งให้ผู้ใช้งานทราบทันที แต่ถ้าเป็นบั๊กที่ไม่ร้ายแรงมากนัก อาจจะปล่อยให้เป็นไปตาม Deprecation Policy แล้วค่อยแก้ไขใน API Version ใหม่
อันนี้ขึ้นอยู่กับความซับซ้อนของการเปลี่ยนแปลง และจำนวนผู้ใช้งาน API Version เก่า ถ้ามีการเปลี่ยนแปลงที่ซับซ้อนมาก และมีผู้ใช้งาน API Version เก่าจำนวนมาก ควรกำหนด Deprecation Policy ให้ยาวนานขึ้น เพื่อให้ผู้ใช้งานมีเวลาในการปรับตัว
ไม่มี Strategy ไหนที่ดีที่สุดสำหรับทุกกรณี ขึ้นอยู่กับความต้องการและความเหมาะสมของแต่ละโปรเจกต์ สิ่งที่สำคัญคือต้องเข้าใจข้อดีข้อเสียของแต่ละ Strategy และเลือกใช้ให้เหมาะสมกับสถานการณ์
การทำ API Versioning เป็นเรื่องที่สำคัญมากในการพัฒนาซอฟต์แวร์ โดยเฉพาะอย่างยิ่งถ้าเราต้องการให้ API ของเรามีความยืดหยุ่น สามารถรองรับการเปลี่ยนแปลงในอนาคต และไม่ส่งผลกระทบต่อผู้ใช้งานเดิม การวางแผนเรื่อง Versioning ตั้งแต่เนิ่นๆ จะช่วยประหยัดเวลาและค่าใช้จ่ายในระยะยาวได้เยอะเลย
อย่าลืมว่าการสื่อสารกับผู้ใช้งาน API เป็นสิ่งสำคัญ แจ้งให้พวกเขาทราบถึงการเปลี่ยนแปลงที่จะเกิดขึ้น และให้เวลาพวกเขาในการปรับตัว
ถ้าใครสนใจเรื่องการลงทุน ลองแวะไปดูที่ iCafeForex ได้นะครับ