Content Negotiation
resource เดียวสามารถมีได้หลาย representation — JSON, CSV, ภาษาต่าง ๆ Content negotiation ให้ client ระบุความต้องการและให้ server เลือกตัวที่ตรงที่สุด ทั้งหมดนี้โดยไม่ต้องเปลี่ยน URI
หลักการทำงาน
หัวข้อที่มีชื่อว่า “หลักการทำงาน”client ส่ง Accept เพื่อบอกว่ารับ media type ไหนได้บ้าง และอาจส่ง Accept-Language มาด้วย จากนั้น server ตอบกลับด้วย representation ที่เลือกแล้ว พร้อม Content-Type ที่ตรงกัน:
GET /reports/42 HTTP/1.1Accept: text/csv, application/json;q=0.8Accept-Language: th, en;q=0.5ค่า q คือน้ำหนักด้านคุณภาพ (quality weight) — ในที่นี้ client อยากได้ CSV มากกว่า ถัดมาจึงเป็น JSON ฝั่ง server ควรเลือก type ที่ดีที่สุดเท่าที่รองรับได้ แล้วประกาศกลับมาใน Content-Type
เมื่อ server ตอบตามที่ขอไม่ได้
หัวข้อที่มีชื่อว่า “เมื่อ server ตอบตามที่ขอไม่ได้”- หาก server ไม่สามารถสร้าง type ใดที่ยอมรับได้เลย ให้ตอบ
406 Not Acceptable - หาก body ของ request มาในรูปแบบ type ที่ server แยกวิเคราะห์ (parse) ไม่ได้ ให้ตอบ
415 Unsupported Media Type
การเจรจาใน API ที่กำลังทำงานจริง
หัวข้อที่มีชื่อว่า “การเจรจาใน API ที่กำลังทำงานจริง”| ข้อดี (Content Negotiation) | ข้อแลกเปลี่ยน |
|---|---|
| API เดียว รองรับหลาย format (JSON, XML, CSV) | server ต้อง implement serializer หลายตัว |
| client บอก server ว่าต้องการ format อะไร | complexity เพิ่ม — content type routing logic |
| versioning ผ่าน media type ที่ RESTful ที่สุด | tooling support สำหรับ custom media type น้อย |
compression ผ่าน Accept-Encoding ลด bandwidth | ต้องระวัง cache key ที่ต้องรวม Accept header |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”ไม่ Return Content-Type ใน Response
อาการ:
- server return JSON แต่ไม่ตั้ง
Content-Type: application/json - client ไม่รู้วิธี parse body — บาง client ถือว่าเป็น plain text
- ตั้ง
Content-Typeทุก response ที่มี body เสมอ
Cache โดยไม่รวม Accept ใน Cache Key
อาการ:
- CDN cache response ของ
GET /reportsที่ขอ JSON - request ถัดไปขอ CSV — CDN return JSON เดิม
- ตั้ง
Vary: Acceptheader เพื่อให้ CDN รวม Accept ใน cache key
💡 ตัวอย่างจากของจริง
GitHub API:
Accept: application/vnd.github+jsonสำหรับ standard JSONAccept: application/vnd.github.rawสำหรับ raw file content- format ต่างกันผ่าน Accept header โดยไม่ต้องเปลี่ยน URI
AWS API:
Accept-Encoding: gzip— response body compress อัตโนมัติ- ลด bandwidth สำหรับ large JSON response เช่น list operation