ข้ามไปยังเนื้อหา

Consistency & Conventions

กฎแต่ละข้อนั้นสำคัญน้อยกว่าการนำไปใช้ทุกที่ API ที่สอดคล้อง 90% สร้างความสับสนมากกว่า API ที่พิลึกอย่างสม่ำเสมอ เพราะข้อยกเว้นคือจุดที่บั๊กและ support ticket ไปอาศัยอยู่

ตัดสินใจเรื่องเหล่านี้ให้ครบทั้ง API แล้วจดเอาไว้:

  • รูปแบบตัวพิมพ์ของ fieldcamelCase หรือ snake_case ให้เหมือนกันในทุก response
  • พหูพจน์ — ทุก collection เป็นพหูพจน์ (/articles, /users) อย่าปนกัน
  • ID — รูปแบบเดียว (UUID, ULID หรือ integer) และชื่อ field เดียว (id)
  • Timestamps — string แบบ ISO 8601 UTC (2026-06-24T10:00:00Z) พร้อมชื่อ field ที่สอดคล้องกันอย่าง createdAt/updatedAt
  • เงินและ enum — ใช้หน่วยย่อย (integer) สำหรับเงิน ใช้ string enum ที่มี doc กำกับ ไม่ใช่ตัวเลขปริศนา (magic number)

resource ส่วนใหญ่เป็น item ใน collection (/articles/42) มีบางตัวที่เป็น singleton คือมีอยู่หนึ่งเดียวต่อบริบทหนึ่ง จึงไม่มี ID:

GET /me # the authenticated user
GET /settings # the account's settings
PATCH /settings # update them

singleton จงใจข้ามระดับ collection ไป อย่าไปคิด ID ปลอม ๆ ขึ้นมาใส่

  • collection เป็นพหูพจน์ ส่วน item เป็น /collection/\{id\}
  • path ตัวพิมพ์เล็กคั่นด้วยขีดกลาง ไม่มีคำกริยา ไม่มีนามสกุลไฟล์
  • รูปแบบตัวพิมพ์เดียว รูปแบบ ID เดียว รูปแบบ timestamp เดียว ในทุก resource
  • error ใช้โครงสร้างร่วมกันแบบเดียว (กล่าวถึงใน Status Codes & Errors)
  • field เดียวกันหมายถึงสิ่งเดียวกันทุกที่
ข้อดี (Consistency)ข้อแลกเปลี่ยน
developer onboarding เร็ว — เดา endpoint ได้ต้องตกลง convention ก่อน — ใช้เวลา upfront
SDK generation และ documentation ง่ายกว่าconvention บางอย่างไม่เหมาะทุก resource
client code สม่ำเสมอ — ไม่มี special casebreaking เมื่อต้องเปลี่ยน convention ในภายหลัง
ลด bug จาก typo หรือ case ผิดteam ต้องยึดตาม — ต้องการ linting หรือ review process

Response Format ไม่สม่ำเสมอ อาการ:

  • endpoint หนึ่ง return { data: [...] } อีก endpoint return [...] ตรง ๆ
  • error response: บาง endpoint ส่ง { error: "..." } บาง endpoint ส่ง { message: "..." }
  • กำหนด response envelope มาตรฐาน และยึดตลอด API

Date Format ไม่สม่ำเสมอ อาการ:

  • createdAt: "2024-01-15" ในบาง endpoint, created: "15/01/2024" ในอีก endpoint
  • client ต้องแปลง format ต่างกันในแต่ละ call
  • ใช้ ISO 8601 (2024-01-15T10:30:00Z) สม่ำเสมอทั้ง API

💡 ตัวอย่างจากของจริง

Stripe API:

  • ทุก resource มี id, object, created, livemode — consistent metadata
  • error format เหมือนกันทุก endpoint: { error: { type, code, message, param } }

GitHub API:

  • ทุก response มี X-RateLimit-* headers สม่ำเสมอ
  • pagination ผ่าน Link header ทุก collection endpoint
ทำไมความสอดคล้องเพียงบางส่วนจึงมักแย่กว่าการพิลึกอย่างสม่ำเสมอ?
ควรอ้างถึง singleton resource อย่าง user ปัจจุบันอย่างไร?
รูปแบบที่แนะนำสำหรับ timestamp ใน response คืออะไร?