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

Field Selection

เหตุผลหนึ่งที่ทีมหันไปใช้ GraphQL คือ over-fetching: endpoint คืนมา 30 field ทั้งที่ client ต้องการแค่ 3 ตัว ฝั่ง REST เองก็ให้การควบคุมแบบเดียวกันได้ ด้วย query parameter ง่าย ๆ สองตัว

ให้ client ระบุรายการ field ที่ต้องการด้วย ?fields=:

GET /articles?fields=id,title

server จะคืนเฉพาะ key เหล่านั้น วิธีนี้ช่วยลดขนาด payload สำหรับ client บนมือถือและสำหรับ list view อีกทั้งยังบ่งบอกเจตนาด้วย จงใส่ identifier ของ resource มาด้วยเสมอแม้จะไม่ได้ร้องขอ เพื่อให้ response ยังคงระบุที่อยู่ (addressable) ได้

ค่าเริ่มต้นควรเป็นการ link ไปยัง resource ที่เกี่ยวข้อง ไม่ใช่ฝัง (embed) เข้ามาทั้งก้อน ถ้า client อยากได้แบบ inline ก็เปิดใช้เองได้ด้วย ?expand=:

GET /articles/42?expand=author

ถ้าไม่ใส่ expand ตัว author จะเป็น reference ({ "id": 7, "href": "/users/7" }) แต่ถ้าใส่ ระบบจะฝัง object ของ author เข้ามาให้เลย วิธีนี้ทำให้ response เริ่มต้นมีขนาดเล็ก และยังตัด round trip เพิ่มออกไปได้เมื่อ client ต้องการข้อมูลที่เกี่ยวข้องจริง ๆ

JavaScript
ข้อดี (Field Selection)ข้อแลกเปลี่ยน
ลด payload — mobile network ประหยัด bandwidthserver ต้อง parse fields parameter และ filter response
ลด over-fetching — ดึงเฉพาะที่ต้องการresponse shape ต่างกันตาม request — caching ซับซ้อน
ลด serialization time บน serverdocumentation ยากกว่า — response ไม่ fixed
client มีความยืดหยุ่นสูงถ้าต้องการ flexible มาก GraphQL อาจเหมาะกว่า

Field Selection ที่ไม่ Consistent อาการ:

  • ?fields=name,email บาง endpoint, ?select=name,email อีก endpoint
  • developer ต้องจำ parameter name ต่างกัน
  • ใช้ fields หรือ select สม่ำเสมอทั้ง API

ไม่มี Fallback เมื่อ Field ไม่มีอยู่ อาการ:

  • ?fields=name,nonExistentField — server return 500 หรือ omit field โดยไม่แจ้ง
  • client ไม่รู้ว่า field ที่ขาดหายไปเพราะ null หรือเพราะ field ไม่มี
  • return 400 เมื่อ field ไม่มีอยู่ หรือ ignore gracefully และ document behavior

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

Google APIs:

  • ?fields=items(id,title,description) — เลือก field ได้ถึงระดับ nested
  • ลด response size สำหรับ mobile client ที่ bandwidth จำกัด

LinkedIn API:

  • projection parameter: ?projection=(id,localizedName,localizedHeadline)
  • ลด response จาก 50+ field เหลือ field ที่ต้องการจริง
`?fields=id,title` เป็นการร้องขออะไร?
parameter `?expand=author` มีไว้ทำอะไร?
ทำไมต้องใส่ identifier มาด้วยเสมอแม้จะไม่ได้อยู่ใน `fields`?